Início › Info de modding › Portar um mutador antigo
Capítulo 05

Portar um mutador antigo

O KroggyComm 1.1, dos arquivos compactados originais a um pacote, e um arquivo de regras do TA: Mutation mantido com sm ou reescrito em Lua.

Este capítulo resume docs/mutators/authoring.md e docs/mutators/oamut-standard.md.

Os arquivos compactados originais

O KroggyComm 1.1, de Immerman, saiu como }{KroggyComm11.tam e }{KroggyComm11.ccx. O .tam é o registro do TA: Mutation: o nome, o texto que dá crédito ao autor e os códigos de compatibilidade TACC e UH. O .ccx contém o modelo do Krogoth, um script de comandante guardado duas vezes (para o ARM e para o CORE), os arquivos de unidade dos dois comandantes, o código-fonte do script e os destroços. Este capítulo não reproduz esses arquivos compactados. Ele mostra o que o pacote curado mantém e para onde foi cada parte.

Comece pela importação

oa-tool mutator import lê o .tam e encontra o .ccx ao lado dele. Escreva a pasta num lugar diferente da pasta que contém o .tam. Os avisos dizem o que curar: a tag é a padrão, TACC vira ta-3.1c, e UH não tem mod correspondente.

$ 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

A importação mantém o .ccx inteiro em files/kroggycomm-1-1.ccx, e o script que ela escreve só acrescenta essa pasta. O manifesto tem a versão 1.0, a tag gameplay, works-with ta-3.1c, a camada files e o registro legacy. Essa pasta já roda, e ela é o começo do pacote, não o mutador pronto.

Importação · 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

Modelo e scripts viram files/

O pacote curado mantém só o que o jogo lê do arquivo compactado: três caminhos em files/, cada um onde o jogo o procura.

files/objects3d/KROGCOM.3doo modelo, de objects3d/KROGCOM.3do no .ccxfiles/scripts/armcom.cobo script do ARM, de scripts/armcom.cobfiles/scripts/corcom.cobo script do CORE: os mesmos bytes do script do ARM, guardados no arquivo compactado como scripts/Corcom.cob

Os dois arquivos de unidade também não são distribuídos: seus campos viram regras, mais abaixo. Outras duas coisas do arquivo compactado ficam de fora. scripts/KroggyCom.bos é o código-fonte do script, e o jogo nunca o lê. features/corpses/Corkrog_dead.tdf são os destroços do Core Contingency, sem mudanças.

As mudanças no FBI viram regras

Os campos de unidade do Krogoth viram as regras do mutator.lua curado. Os dois comandantes recebem o objeto KROGCOM, as armas CORKROG_FIRE, CORKROG_ROCKET e CORKROG_HEAD, os custos, a área ocupada e o movimento. Os campos de camuflagem e de alvo ruim são removidos, o que faz parte desse design. HealTime, OvrAdjust e DefaultMissionType mantêm os valores do 3.1c: os arquivos de unidade de 2001 são anteriores a esses campos, então a ausência deles não faz parte do design do Krogoth. A categoria de som do ARM vira KROGOTH. O CORE mantém CORE_COM, então o script passa nil e não define soundcategory. O hook de unidades recusa a partida quando essas três armas estão faltando.

Script de entrada · 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

O bloco legacy e o crédito

legacy identifica o original. Mantenha o registro que a importação escreveu: o nome KroggyComm 1.1, o prefixo }{, a compatibilidade TACC e UH, e os arquivos }{KroggyComm11.tam e }{KroggyComm11.ccx. O autor continua sendo Immerman, e a descrição cita o original que o pacote substitui e o autor dele: esse é o crédito. O resto é curado: versão 1, as tags commanders e new-units, works-with com asterisco, para que o pacote sirva para qualquer mod e para o jogo base, e as camadas files e units para os arquivos, as regras e o hook. conflicts-with cita anni-comm, special-tech-comm, commander-blast e tribe-commander, que escrevem os mesmos campos de comandante ou distribuem o mesmo script. O manifesto abaixo é o arquivo inteiro.

Manifesto · 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"]

Verificar e comparar com a importação

De fora da pasta, pack escreve kroggy-comm-1.oamut. oa-tool mutator check lê esse arquivo. Neste pacote, a última linha é result: ok. O diff compara a pasta curada com a importação kroggycomm-1-1. Ele foi rodado a partir da pasta de build dos comandantes, com o arquivo de permissões da família, e DIR representa a pasta do jogo. O arquivo de permissões diz o que pode restar.

$ 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

Com esse arquivo de permissões, a comparação sai com 0. Depois das linhas de cabeçalho, que começam com #, ela imprime as linhas abaixo: 0 differences, 7 allowed, 0 unused allowances. As sete linhas são a importação, do lado direito, perdendo defaultmissiontype, healtime e ovradjust nos dois comandantes e ganhando scripts/kroggycom.bos. O pacote curado mantém esses três campos e não distribui o .bos. Na pasta do jogo usada nessa execução, o hook de unidades não recusou o pacote: as três armas do Krogoth estavam presentes.

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

Um arquivo de regras do TA: Mutation

Os pacotes curados não distribuem arquivos .sm. oa-tool mutator import mantém o arquivo de regras original e o cita no plano com sm. Hide Damage, de Kirk, é o mais curto. A importação escreve rules/hide-damage.sm e um mutator.lua cuja entrada rules é sm "rules/hide-damage.sm". O .sm abaixo é esse arquivo, com suas quebras de linha originais.

Importação · 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
Arquivo de regras · rules/hide-damage.sm
[*all*]
{
HideDamage=1;
}

A mesma regra em Lua é all():change { hidedamage = set(1) }. É nisso que [*all*] e HideDamage=1 se transformam. O pacote curado distribui esse script, não o .sm. O registro legacy dele ainda cita {}HideDamage.tam e {}HideDamage.sm, e o autor continua sendo Kirk.

Script de entrada · mutator.lua
function mutate(ctx)
  return {
    rules = {
      all():change { hidedamage = set(1) },
    },
  }
end
Manifesto · 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"]

O comando é oa-tool mutator import INPUT... --out DIR. Acrescente --id, --version, --tag, --works-with, --pack e --force quando precisar. Um .sm é copiado para rules/, e o plano o cita com sm. A importação é o começo do pacote. Antes de publicar, transforme as variantes em opções, transforme os arquivos de regras nas formas Lua ou deixe-os citados com sm, e mantenha um arquivo só onde um modelo ou um script precisa dele.