Merge branch 'master' of git://github.com/angavrilov/dfhack
commit
962a057ffa
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1 +1 @@
|
||||
Subproject commit 8a78bfa218817765b0a80431e0cf25435ffb2179
|
||||
Subproject commit d52c7181fb439a5fead143188d17d659d82e7f89
|
@ -1 +1 @@
|
||||
Subproject commit 37a823541538023b9f3d0d1e8039cf32851de68d
|
||||
Subproject commit 2a62ba5ed2607f4dbf0473e77502d4e19c19678e
|
@ -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
|
@ -0,0 +1,109 @@
|
||||
-- Wakes up the sleeping, breaks up parties and stops breaks.
|
||||
|
||||
local utils = require 'utils'
|
||||
|
||||
local args = {...}
|
||||
local burrows = {}
|
||||
local bnames = {}
|
||||
|
||||
if not dfhack.isMapLoaded() then
|
||||
qerror('Map is not loaded.')
|
||||
end
|
||||
|
||||
for _,v in ipairs(args) do
|
||||
local b = dfhack.burrows.findByName(v)
|
||||
if not b then
|
||||
qerror('Unknown burrow: '..v)
|
||||
end
|
||||
table.insert(bnames, v)
|
||||
table.insert(burrows, b)
|
||||
end
|
||||
|
||||
function is_in_burrows(pos)
|
||||
if #burrows == 0 then
|
||||
return true
|
||||
end
|
||||
for _,v in ipairs(burrows) do
|
||||
if dfhack.burrows.isAssignedTile(v, pos) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function add_thought(unit, code)
|
||||
for _,v in ipairs(unit.status.recent_events) do
|
||||
if v.type == code then
|
||||
v.age = 0
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
unit.status.recent_events:insert('#', { new = true, type = code })
|
||||
end
|
||||
|
||||
function wake_unit(unit)
|
||||
local job = unit.job.current_job
|
||||
if not job or job.job_type ~= df.job_type.Sleep then
|
||||
return
|
||||
end
|
||||
|
||||
if job.completion_timer > 0 then
|
||||
unit.counters.unconscious = 0
|
||||
add_thought(unit, df.unit_thought_type.SleepNoiseWake)
|
||||
elseif job.completion_timer < 0 then
|
||||
add_thought(unit, df.unit_thought_type.Tired)
|
||||
end
|
||||
|
||||
job.pos:assign(unit.pos)
|
||||
|
||||
job.completion_timer = 0
|
||||
|
||||
unit.path.dest:assign(unit.pos)
|
||||
unit.path.path.x:resize(0)
|
||||
unit.path.path.y:resize(0)
|
||||
unit.path.path.z:resize(0)
|
||||
|
||||
unit.counters.job_counter = 0
|
||||
end
|
||||
|
||||
function stop_break(unit)
|
||||
local counter = dfhack.units.getMiscTrait(unit, df.misc_trait_type.OnBreak)
|
||||
if counter then
|
||||
counter.id = df.misc_trait_type.TimeSinceBreak
|
||||
counter.value = 100800 - 30*1200
|
||||
add_thought(unit, df.unit_thought_type.Tired)
|
||||
end
|
||||
end
|
||||
|
||||
-- Stop rest
|
||||
for _,v in ipairs(df.global.world.units.active) do
|
||||
local x,y,z = dfhack.units.getPosition(v)
|
||||
if x and not dfhack.units.isDead(v) and is_in_burrows(xyz2pos(x,y,z)) then
|
||||
wake_unit(v)
|
||||
stop_break(v)
|
||||
end
|
||||
end
|
||||
|
||||
-- Stop parties
|
||||
for _,v in ipairs(df.global.ui.parties) do
|
||||
local pos = utils.getBuildingCenter(v.location)
|
||||
if is_in_burrows(pos) then
|
||||
v.timer = 0
|
||||
for _, u in ipairs(v.units) do
|
||||
add_thought(unit, df.unit_thought_type.Tired)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local place = 'the halls and tunnels'
|
||||
if #bnames > 0 then
|
||||
if #bnames == 1 then
|
||||
place = bnames[1]
|
||||
else
|
||||
place = table.concat(bnames,', ',1,#bnames-1)..' and '..bnames[#bnames]
|
||||
end
|
||||
end
|
||||
dfhack.gui.showAnnouncement(
|
||||
'A loud siren sounds throughout '..place..', waking the sleeping and startling the awake.',
|
||||
COLOR_BROWN, true
|
||||
)
|
Loading…
Reference in New Issue