홈 › 모딩 정보 › 구형 뮤테이터 이식하기
05장

구형 뮤테이터 이식하기

KroggyComm 1.1을 아카이브에서 패키지로 옮기기, 그리고 TA: Mutation 규칙 파일을 sm으로 유지하거나 Lua로 다시 쓰기.

이 장은 docs/mutators/authoring.md 문서와 docs/mutators/oamut-standard.md 문서를 요약합니다.

원래 아카이브

Immerman의 KroggyComm 1.1은 }{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.ccx의 objects3d/KROGCOM.3do에서 가져온 모델files/scripts/armcom.cobscripts/armcom.cob에서 가져온 ARM 스크립트files/scripts/corcom.cobCORE 스크립트: 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, 접두사 }{, 호환성 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.yaml
oamut: 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개, 허용 7개, 사용하지 않은 허용 0개입니다. 일곱 줄은 오른쪽인 가져오기 결과가 두 커맨더 모두에서 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으로 지정합니다. Kirk의 Hide Damage가 짧은 예입니다. 가져오기는 rules/hide-damage.sm과, rules 항목이 sm "rules/hide-damage.sm"인 mutator.lua를 씁니다. 아래 .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.lua
function mutate(ctx)
  return {
    rules = {
      all():change { hidedamage = set(1) },
    },
  }
end
매니페스트 · oamut.yaml
oamut: 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으로 지정한 채 두며, 모델이나 스크립트에 필요한 곳에만 파일을 남기세요.