Add a devel script to inject raw definitions into an existing world.
parent
7a06c949c7
commit
f7e414e397
@ -0,0 +1,178 @@
|
||||
-- Injects new reaction, item and building defs into the world.
|
||||
|
||||
-- The savegame contains a list of the relevant definition tokens in
|
||||
-- the right order, but all details are read from raws every time.
|
||||
-- This allows just adding stub definitions, and simply saving and
|
||||
-- reloading the game.
|
||||
|
||||
local utils = require 'utils'
|
||||
|
||||
local raws = df.global.world.raws
|
||||
|
||||
print[[
|
||||
WARNING: THIS SCRIPT CAN PERMANENLY DAMAGE YOUR SAVE.
|
||||
|
||||
This script attempts to inject new raw objects into your
|
||||
world. If the injected references do not match the actual
|
||||
edited raws, your save will refuse to load, or load but crash.
|
||||
]]
|
||||
|
||||
if not utils.prompt_yes_no('Did you make a backup?') then
|
||||
qerror('Not backed up.')
|
||||
end
|
||||
|
||||
df.global.pause_state = true
|
||||
|
||||
local changed = false
|
||||
|
||||
function inject_reaction(name)
|
||||
for _,v in ipairs(raws.reactions) do
|
||||
if v.code == name then
|
||||
print('Reaction '..name..' already exists.')
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
print('Injecting reaction '..name)
|
||||
changed = true
|
||||
|
||||
raws.reactions:insert('#', {
|
||||
new = true,
|
||||
code = name,
|
||||
name = 'Dummy reaction '..name,
|
||||
index = #raws.reactions,
|
||||
})
|
||||
end
|
||||
|
||||
local building_types = {
|
||||
workshop = { df.building_def_workshopst, raws.buildings.workshops },
|
||||
furnace = { df.building_def_furnacest, raws.buildings.furnaces },
|
||||
}
|
||||
|
||||
function inject_building(btype, name)
|
||||
for _,v in ipairs(raws.buildings.all) do
|
||||
if v.code == name then
|
||||
print('Building '..name..' already exists.')
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
print('Injecting building '..name)
|
||||
changed = true
|
||||
|
||||
local typeinfo = building_types[btype]
|
||||
|
||||
local id = raws.buildings.next_id
|
||||
raws.buildings.next_id = id+1
|
||||
|
||||
raws.buildings.all:insert('#', {
|
||||
new = typeinfo[1],
|
||||
code = name,
|
||||
name = 'Dummy '..btype..' '..name,
|
||||
id = id,
|
||||
})
|
||||
|
||||
typeinfo[2]:insert('#', raws.buildings.all[#raws.buildings.all-1])
|
||||
end
|
||||
|
||||
local itemdefs = raws.itemdefs
|
||||
local item_types = {
|
||||
weapon = { df.itemdef_weaponst, itemdefs.weapons, 'weapon_type' },
|
||||
trainweapon = { df.itemdef_weaponst, itemdefs.weapons, 'training_weapon_type' },
|
||||
pick = { df.itemdef_weaponst, itemdefs.weapons, 'digger_type' },
|
||||
trapcomp = { df.itemdef_trapcompst, itemdefs.trapcomps, 'trapcomp_type' },
|
||||
toy = { df.itemdef_toyst, itemdefs.toys, 'toy_type' },
|
||||
tool = { df.itemdef_toolst, itemdefs.tools, 'tool_type' },
|
||||
instrument = { df.itemdef_instrumentst, itemdefs.instruments, 'instrument_type' },
|
||||
armor = { df.itemdef_armorst, itemdefs.armor, 'armor_type' },
|
||||
ammo = { df.itemdef_ammost, itemdefs.ammo, 'ammo_type' },
|
||||
siegeammo = { df.itemdef_siegeammost, itemdefs.siege_ammo, 'siegeammo_type' },
|
||||
gloves = { df.itemdef_glovest, itemdefs.gloves, 'gloves_type' },
|
||||
shoes = { df.itemdef_shoest, itemdefs.shoes, 'shoes_type' },
|
||||
shield = { df.itemdef_shieldst, itemdefs.shields, 'shield_type' },
|
||||
helm = { df.itemdef_helmst, itemdefs.helms, 'helm_type' },
|
||||
pants = { df.itemdef_pantsst, itemdefs.pants, 'pants_type' },
|
||||
food = { df.itemdef_foodst, itemdefs.food },
|
||||
}
|
||||
|
||||
function add_to_civ(entity, bvec, id)
|
||||
for _,v in ipairs(entity.resources[bvec]) do
|
||||
if v == id then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
entity.resources[bvec]:insert('#', id)
|
||||
end
|
||||
|
||||
function add_to_dwarf_civs(btype, id)
|
||||
local typeinfo = item_types[btype]
|
||||
if not typeinfo[3] then
|
||||
print('Not adding to civs.')
|
||||
end
|
||||
|
||||
for _,entity in ipairs(df.global.world.entities.all) do
|
||||
if entity.race == df.global.ui.race_id then
|
||||
add_to_civ(entity, typeinfo[3], id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function inject_item(btype, name)
|
||||
for _,v in ipairs(itemdefs.all) do
|
||||
if v.id == name then
|
||||
print('Itemdef '..name..' already exists.')
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
print('Injecting item '..name)
|
||||
changed = true
|
||||
|
||||
local typeinfo = item_types[btype]
|
||||
local vec = typeinfo[2]
|
||||
local id = #vec
|
||||
|
||||
vec:insert('#', {
|
||||
new = typeinfo[1],
|
||||
id = name,
|
||||
subtype = id,
|
||||
name = name,
|
||||
name_plural = name,
|
||||
})
|
||||
|
||||
itemdefs.all:insert('#', vec[id])
|
||||
|
||||
add_to_dwarf_civs(btype, id)
|
||||
end
|
||||
|
||||
local args = {...}
|
||||
local mode = nil
|
||||
local ops = {}
|
||||
|
||||
for _,kv in ipairs(args) do
|
||||
if mode and string.match(kv, '^[%u_]+$') then
|
||||
table.insert(ops, curry(mode, kv))
|
||||
elseif kv == 'reaction' then
|
||||
mode = inject_reaction
|
||||
elseif building_types[kv] then
|
||||
mode = curry(inject_building, kv)
|
||||
elseif item_types[kv] then
|
||||
mode = curry(inject_item, kv)
|
||||
else
|
||||
qerror('Invalid option: '..kv)
|
||||
end
|
||||
end
|
||||
|
||||
if #ops > 0 then
|
||||
print('')
|
||||
for _,v in ipairs(ops) do
|
||||
v()
|
||||
end
|
||||
end
|
||||
|
||||
if changed then
|
||||
print('\nNow without unpausing save and reload the game to re-read raws.')
|
||||
else
|
||||
print('\nNo changes made.')
|
||||
end
|
Loading…
Reference in New Issue