diff options
| -rw-r--r-- | scripts/devel/inject-raws.lua | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/scripts/devel/inject-raws.lua b/scripts/devel/inject-raws.lua new file mode 100644 index 00000000..a4ebeec1 --- /dev/null +++ b/scripts/devel/inject-raws.lua @@ -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 |
