Перенос старого мутатора
KroggyComm 1.1 из исходных архивов в пакет, а также файл правил TA: Mutation, оставленный через sm или переписанный на Lua.
Эта глава кратко пересказывает docs/mutators/authoring.md и docs/mutators/oamut-standard.md.
Исходные архивы
KroggyComm 1.1 от Immerman распространялся как }{KroggyComm11.tam и }{KroggyComm11.ccx. Файл .tam — это запись TA: Mutation: название, текст с упоминанием автора и коды совместимости TACC и UH. В .ccx лежат модель Крогота, один скрипт Командира, сохранённый дважды (для ARM и для CORE), файлы юнитов двух Командиров, исходник скрипта и обломки. Эта глава не воспроизводит сами архивы. Она показывает, что сохраняет подготовленный пакет и куда ушла каждая часть.
Начните с импорта
oa-tool mutator import читает .tam и находит рядом .ccx. Пишите папку куда-нибудь вне папки, где лежит .tam. Предупреждения подскажут, что нужно доработать вручную: тег стоит по умолчанию, TACC превращается в ta-3.1c, а для UH нет мода, которому он соответствует.
$ oa-tool mutator import 'originals/}{KroggyComm11.tam' --out imports
imported kroggycomm-1-1 from originals/}{KroggyComm11.tam: 0 rule files, 1 archives
tags default to gameplay
TACC maps to ta-3.1c; Core Contingency's units are only there when it is on
UH is not mapped to a mod
Импорт сохраняет весь .ccx как files/kroggycomm-1-1.ccx, а скрипт, который он пишет, только добавляет эту папку. В его манифесте версия 1.0, тег gameplay, works-with ta-3.1c, слой files и запись legacy. В эту папку уже можно играть, но это начало пакета, а не готовый мутатор.
Импорт ·mutator.lua-- Made by oa-tool mutator import from the TA: Mutation mutator "KroggyComm 1.1".
-- Its rule file is in rules/ and its archives in files/; files OA protects are left out.
function mutate(ctx)
return {
files = { add = { "files" } },
}
end
Модель и скрипты переходят в files/
Подготовленный пакет сохраняет только то, что игра читает из архива: три пути в files/, каждый там, где игра его ищет.
files/objects3d/KROGCOM.3doмодель, из objects3d/KROGCOM.3do в .ccxfiles/scripts/armcom.cobскрипт ARM, из scripts/armcom.cobfiles/scripts/corcom.cobскрипт CORE: те же байты, что у ARM, в архиве лежит как scripts/Corcom.cobДва файла юнитов тоже не поставляются: их поля становятся правилами, о них ниже. Ещё две вещи из архива опущены. scripts/KroggyCom.bos — исходник скрипта, и игра его никогда не читает. features/corpses/Corkrog_dead.tdf — обломки из Core Contingency без изменений.
Изменения FBI становятся правилами
Поля юнита Крогота становятся правилами в подготовленном mutator.lua. Оба Командира получают объект KROGCOM, оружие CORKROG_FIRE, CORKROG_ROCKET и CORKROG_HEAD, стоимость, площадь основания и параметры движения. Поля маскировки и bad-target удаляются, это часть того замысла. HealTime, OvrAdjust и DefaultMissionType сохраняют значения 3.1c: файлы юнитов 2001 года старше этих полей, так что их отсутствие — не часть замысла Крогота. Категория звука ARM становится KROGOTH. CORE сохраняет CORE_COM, поэтому скрипт передаёт nil и не задаёт soundcategory. Хук units отклоняет матч, если этих трёх видов оружия нет.
Входной скрипт ·mutator.lua-- HealTime, OvrAdjust, DefaultMissionType and the localized names stay.
-- The 2001 unit files predate those 3.1c fields, so their absence is not the Krogoth's design.
local function krogoth_changes(sound)
local changes = {
acceleration = set(0.09),
badtargetcategory = remove(),
brakerate = set(0.19),
buildcostenergy = set(116664),
buildcostmetal = set(29489),
builddistance = set(120),
buildtime = set(382193),
cantbetransported = set(1),
cloakcost = remove(),
cloakcostmoving = remove(),
corpse = set("corkrog_dead"),
downloadable = set(1),
energymake = set(32),
energyuse = set(7),
explodeas = set("NUCLEAR_MISSILE"),
footprintx = set(3),
footprintz = set(3),
maxdamage = set(29918),
maxslope = set(17),
maxvelocity = set(1),
maxwaterdepth = set(12),
mincloakdistance = remove(),
movementclass = set("TANKDH3"),
noautofire = set(0),
objectname = set("KROGCOM"),
onoffable = set(1),
selfdestructas = set("NUCLEAR_MISSILE"),
sightdistance = set(255),
turnrate = set(960),
weapon1 = set("CORKROG_FIRE"),
weapon2 = set("CORKROG_ROCKET"),
weapon3 = set("CORKROG_HEAD"),
wpri_badtargetcategory = remove(),
}
if sound ~= nil then
changes.soundcategory = set(sound)
end
return changes
end
function mutate(ctx)
return {
files = { add = { "files" } },
rules = {
named("ARMCOM"):change(krogoth_changes("KROGOTH")),
named("CORCOM"):change(krogoth_changes(nil)),
},
units = function(units, ctx)
local weapons = ctx.weapons
if weapons["CORKROG_FIRE"] == nil or weapons["CORKROG_ROCKET"] == nil or weapons["CORKROG_HEAD"] == nil then
ctx.incompatible("KroggyComm needs Core Contingency's Krogoth weapons")
end
end,
}
end
Блок legacy и упоминание автора
legacy называет оригинал. Оставьте запись, которую написал импорт: название KroggyComm 1.1, префикс }{, compatibility TACC и UH и файлы }{KroggyComm11.tam и }{KroggyComm11.ccx. Автором остаётся Immerman, а в описании названы заменяемый оригинал и его автор: так и отдаётся должное автору. Остальное подготовлено вручную: версия 1, теги commanders и new-units, works-with со звёздочкой, так что пакет подходит к любому моду и основной игре, и слои files и units для файлов, правил и хука. conflicts-with называет anni-comm, special-tech-comm, commander-blast и tribe-commander, которые пишут те же поля Командира или поставляют тот же скрипт. Ниже приведён манифест целиком.
Манифест ·oamut.yamloamut: 1
id: "kroggy-comm"
name: "Krogoth Commander"
version: "1"
author:
name: "Immerman"
description: "Use an amphibious Krogoth as a commander. Turn it off to disable the radar, the sonar and the head laser in exchange for 7 energy. The D-gun aims the head laser. Arm and Core are both named because one script is shipped for each commander. This package replaces KroggyComm 1.1 by Immerman. The model and the scripts stay as files, and the Krogoth's stats are rules, including the cloak and bad-target removals that belong to that design. Heal time, the override adjust, the default mission and the localized names stay, because the 2001 unit files left them out. It needs Core Contingency's Krogoth weapons."
tags: ["commanders", "new-units"]
works-with: ["*"]
requires:
engine: ">= 0.8.5"
conflicts-with: ["anni-comm", "special-tech-comm", "commander-blast", "tribe-commander"]
layers: ["files", "units"]
legacy:
- name: "KroggyComm 1.1"
prefix: "}{"
compatibility: ["TACC", "UH"]
files: ["}{KroggyComm11.tam", "}{KroggyComm11.ccx"]
Проверка и сравнение с импортом
pack, запущенный снаружи папки, пишет kroggy-comm-1.oamut. oa-tool mutator check читает этот файл. Для этого пакета последняя строка — result: ok. diff сравнивает подготовленную папку с импортом kroggycomm-1-1. Его запускали из папки сборки commanders с файлом допусков семейства, а DIR обозначает папку игры. Файл допусков перечисляет, что может остаться.
$ oa-tool mutator pack kroggy-comm
$ oa-tool mutator check kroggy-comm-1.oamut
$ oa-tool mutator diff --game-dir DIR --mutator ./kroggy-comm --versus ./_imports/kroggycomm-1-1 --allow _verify/kroggy-comm.allowed
С этим файлом допусков сравнение завершается с кодом 0. После строк заголовка, которые начинаются с #, оно печатает строки ниже: 0 differences, 7 allowed, 0 unused allowances. Эти семь строк — импорт, то есть правая сторона: у обоих Командиров нет defaultmissiontype, healtime и ovradjust, и добавлен scripts/kroggycom.bos. Подготовленный пакет сохраняет эти три поля и не поставляет .bos. На папке игры из того прогона хук units не отклонил пакет: все три вида оружия Крогота были на месте.
allowed right only field units/armcom.fbi [unitinfo] defaultmissiontype: Standby -> (absent)
allowed right only field units/armcom.fbi [unitinfo] healtime: 27 -> (absent)
allowed right only field units/armcom.fbi [unitinfo] ovradjust: 1 -> (absent)
allowed right only field units/corcom.fbi [unitinfo] defaultmissiontype: Standby -> (absent)
allowed right only field units/corcom.fbi [unitinfo] healtime: 27 -> (absent)
allowed right only field units/corcom.fbi [unitinfo] ovradjust: 1 -> (absent)
allowed right only file added scripts/kroggycom.bos aef95595e9dc1a1e543cf87c954c0b19e6523a227e89c4abaa40e6d264043889
mutator diff: 0 differences, 7 allowed, 0 unused allowances
Файл правил TA: Mutation
Подготовленные пакеты не поставляют файлов .sm. oa-tool mutator import сохраняет исходный файл правил и называет его из плана через sm. Hide Damage от Kirk — короткий пример. Импорт пишет rules/hide-damage.sm и mutator.lua, где запись rules — sm "rules/hide-damage.sm". Ниже — этот файл .sm, включая его окончания строк.
Импорт ·mutator.lua-- Made by oa-tool mutator import from the TA: Mutation mutator "Hide Damage".
-- Its rule file is in rules/ and its archives in files/; files OA protects are left out.
function mutate(ctx)
return {
rules = { sm "rules/hide-damage.sm" },
}
end
Файл правил · rules/hide-damage.sm[*all*]
{
HideDamage=1;
}То же правило на Lua — all():change { hidedamage = set(1) }. Именно в это превращаются [*all*] и HideDamage=1. Подготовленный пакет поставляет этот скрипт, а не .sm. Его запись legacy по-прежнему называет {}HideDamage.tam и {}HideDamage.sm, и автором остаётся Kirk.
Входной скрипт ·mutator.luafunction mutate(ctx)
return {
rules = {
all():change { hidedamage = set(1) },
},
}
end
Манифест · oamut.yamloamut: 1
id: "hide-damage"
name: "Hide Damage"
version: "1"
author:
name: "Kirk"
description: "Opponents cannot see how much health a unit has left.\n\nKirk's Hide Damage sets that flag on every unit.\n\nThis package keeps the flag."
tags: ["gameplay"]
works-with: ["*"]
requires:
engine: ">= 0.8.5"
layers: ["units"]
legacy:
- name: "Hide Damage"
prefix: "{}"
compatibility: ["*"]
files: ["{}HideDamage.tam", "{}HideDamage.sm"]
Команда — oa-tool mutator import INPUT... --out DIR. При необходимости добавьте --id, --version, --tag, --works-with, --pack и --force. Файл .sm копируется в rules/, и план называет его через sm. Импорт — это начало пакета. Перед публикацией превратите варианты в параметры, а файлы правил — в формы Lua, или оставьте их названными через sm, и сохраняйте файл только там, где он нужен модели или скрипту.