v50 Steam/Premium information for editors
- v50 information can now be added to pages in the main namespace. v0.47 information can still be found in the DF2014 namespace. See here for more details on the new versioning policy.
- Use this page to report any issues related to the migration.
This notice may be cached—the current version can be found here.
User:Fleeting Frames/inject-raws
Jump to navigation
Jump to search
Usage: Make a backup of your save. Edit your raws to include new stuff you desire. Open the game and run the command with devel/inject-raws category RAWNAME, with last two being permitted to repeat for injecting multiple different things with 1 command. quicksave, then die, then reload.
-- Inject new raw definitions into the world
--[====[
devel/inject-raws
=================
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.
This script can handle reaction, item, colour and building definitions.
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.
This is useful enough for modders and some users to justify the danger.
Usage example::
devel/inject-raws trapcomp ITEM_TRAPCOMP_STEAM_PISTON workshop STEAM_ENGINE MAGMA_STEAM_ENGINE reaction STOKE_BOILER
]====]
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
function inject_color(colorID)
for _,c in ipairs(raws.language.colors) do
if c.id == colorID then
print('Itemdef '..colorID..' already exists.')
return
end
end
print('Injecting color '..colorID)
changed = true
local newcolor = df.descriptor_color:new()
newcolor.id = colorID
newcolor.words = {[0]=2091} --dummying with Amber
newcolor.name = colorID
newcolor.color = 0
newcolor.bold = 1
newcolor.red = 0
newcolor.green = 0
newcolor.blue = 0
df.global.world.raws.language.colors:insert('#', newcolor)
end
local args = {...}
local mode = nil
local ops = {}
for _,kv in ipairs(args) do
if mode and string.match(kv, '^[%u_ ]+$') then --works with "uppercase words with spaces surrounded by quotation marks"
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)
elseif kv == 'color' then
mode = inject_color
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