Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 2 [3]

Author Topic: Forcing sieges - a script and research  (Read 14261 times)

Bumber

  • Bay Watcher
  • REMOVE KOBOLD
    • View Profile
Re: Forcing sieges - a script and research
« Reply #30 on: August 17, 2020, 09:11:27 pm »

So I decided to try this script again ( -civ HUMAN -race [HUMAN] -count [5] ) but it still didn't work. The error message was something like "couldn't find available civ".

Maybe try with spaces between the brackets: -civ HUMAN -race [ HUMAN ] -count [ 5 ]
Logged
Reading his name would trigger it. Thinking of him would trigger it. No other circumstances would trigger it- it was strictly related to the concept of Bill Clinton entering the conscious mind.

THE xTROLL FUR SOCKx RUSE WAS A........... DISTACTION        the carp HAVE the wagon

A wizard has turned you into a wagon. This was inevitable (Y/y)?

Rumrusher

  • Bay Watcher
  • current project : searching...
    • View Profile
Re: Forcing sieges - a script and research
« Reply #31 on: August 18, 2020, 07:54:33 pm »

so figured why not patch up this script to somewhat not throw out an error 
Code: [Select]
function find_race(name)
    name = name:lower()

    for i,v in ipairs(df.global.world.raws.creatures.all) do
        if v.creature_id:lower() == name:lower() then
            return i
        end
    end
end

function find_entity_for_race(race)
    for i,v in ipairs(df.global.world.entities.all) do
        if v.race == race then
            return i
        end
    end
end

function find_entity_by_name(name)
    name = name:lower()

    for i,v in ipairs(df.global.world.entities.all) do
        if dfhack.TranslateName(v.name, true):lower():find(name) then
            return i
        end
    end
end

function find_cultural_identity(civ)
    for i,v in ipairs(df.global.world.cultural_identities.all) do
        if v.civ_id == civ then
            return i
        end
    end
end



local utils = require 'utils'

validArgs = validArgs or utils.invert({
 'civ',
 'race',
 'count',
 'undead',
 'cleanup',
 'debug',
})

local args = utils.processArgs({...}, validArgs)

if not args.race or not args.count then
    print 'You need to specify at least one race with -race parameter, and count with -count parameter'
    return
end

local race_names = type(args.race) == 'table' and args.race or { args.race }

if type(args.count) == 'table' and #args.race ~= #args.count then
    print 'Number of counts and races provided do not match'
    return
end

local civ_id

if args.civ == 'self' then
    civ_id = df.global.ui.civ_id

elseif args.civ then
    local race_id = find_race(args.civ)
    if race_id then
        civ_id = find_entity_for_race(race_id)

        if not civ_id then
            print ('Could not find a named civilization for race ' .. args.civ)
            return
        end

    else
        civ_id = find_entity_by_name(args.civ)

        if not civ_id then
            print ('Could not find civilization ' .. args.civ)
            return
        end
    end

else
    local race_id = find_race(race_names[1])
    civ_id = race_id and find_entity_for_race(race_id)

    if not civ_id then
        print ('Could not find a named civilization for race ' .. race_names[1])
        return
    end
end

local pop_id = df.historical_entity.find(civ_id).populations[0]
local cult_id = find_cultural_identity(civ_id)

if args.debug then
    print ('Civilization "'.. dfhack.TranslateName(df.historical_entity.find(civ_id).name, true) .. '" ID ' .. civ_id)
end

-- Army
a = df.army:new()
a.id = df.global.army_next_id
df.global.army_next_id = df.global.army_next_id + 1

a.pos.x = 1000 -- can be anything
a.pos.y = 1000
a.last_pos.x = -1
a.last_pos.y = -1
a.unk_10 = 8 -- wait timer, decreased by 16 each tick, siege occurs when reaches zero

for i,race_name in ipairs(race_names) do
    local race_id = find_race(race_name)
    if not race_id then
        print ('Could not find race ' .. race_name)

        --todo: cleanup
        return
    end

    local b = df.army.T_unk_2c:new()
    b.count = type(args.count) == 'table' and args.count[i] or args.count
    b.race = race_id
    b.civ_id = civ_id
    b.population_id = pop_id
    --b.cultural_identity = cult_id

    b.unk_10 = 0 -- -> unit.unk_c0
    b.unk_18 = args.undead and 100 or 0 -- from xml: made creatures undead, so not sure maybe affliction?
    b.unk_1c = 0 -- from xml: crashed df...
    b.unk_20 = 0 -- -> unit.enemy.anon_4
    b.unk_24 = 0 -- -> unit.enemy.anon_5
    b.unk_28 = 0

    a.unk_2c:insert(0,b)
end

a.unk_3c = 50
a.unk_pos_x:insert(0,df.global.world.map.region_x*3)
a.unk_pos_y:insert(0,df.global.world.map.region_y*3)
a.unk_70:insert(0,100)
a.unk_80:insert(0,20)
a.unk_9c = 50
a.unk_a0 = 50
a.unk_a4 = 100

s = df.new('string')
s.value='GENERAL_POISON'
a.creature_class:insert(0,s)

-- Max(TM) pointed out these might be a tent material
a.item_type = 54
a.mat_type = 37
a.mat_index = 184

ac = df.army_controller:new()

ac.id=df.global.army_controller_next_id
df.global.army_controller_next_id = df.global.army_controller_next_id + 1
-- also ac.id -> unit.enemy.anon_6

-- Army controller
ac.entity_id = civ_id
ac.site_id = df.global.ui.site_id
ac.pos_x = df.global.world.map.region_x*3
ac.pos_y = df.global.world.map.region_y*3
--ac.unk_14 = 50
--ac.unk_18 = -1
ac.year = df.global.cur_year
ac.year_tick = df.global.cur_year_tick

ac.unk_34 = -1 -- these two are ids of other army controllers, some kind of relationship
--ac.unk_38 = -1

-- Hesperid mentioned these are army leader and the civ leader, they will be visible in legends if present
--ac.unk_3c = -1
--ac.unk_40 = -1 -- -> history_event_war_attacked_sitest.attacker_general_hf

--ac.unk_54 = 0
ac.type = 2

-- Something
t = df.new('char',100)

t[0]=4 --4
t[4]=1 --1

t[8]=-1 -- all -1
t[9]=-1
t[10]=-1
t[11]=-1

t[12]=-1 -- all -1
t[13]=-1
t[14]=-1
t[15]=-1

--0x42 0x07 0x00 0x00 0x7f 0x1b 0x00 0x00

t[0x5c] = 0x42 --1858
t[0x5d] = 0x7

t[0x60] = 0x7f --7039
t[0x61] = 0x1b

--ac.unk_58 = t

if args.debug then
    print('Army ID ' .. a.id)
    print('Controller ID ' .. ac.id)
end

a.controller_id=ac.id
a.controller=ac

df.global.world.army_controllers.all:insert(#df.global.world.army_controllers.all,ac)
df.global.world.armies.all:insert(#df.global.world.armies.all,a)

-- Experimental
if args.cleanup then
    df.global.pause_state = false
    df.global.gview.view.child:logic()
    df.global.pause_state = true

    utils.erase_sorted_key(df.global.world.army_controllers.all, ac.id, 'id')

    for i,unit in ipairs(df.global.world.units.all) do
        if unit.enemy.anon_6 == ac.id then
            unit.enemy.anon_6 = -1
        end
    end

    df.delete(t)
    ac.unk_58 = nil
    ac:delete()
end
So most of this probably doesn't work fully but I pretty much comment out a few old values that gave out errors and updated a few I know that worked.
Logged
I thought I would I had never hear my daughter's escapades from some boy...
DAMN YOU RUMRUSHER!!!!!!!!
"body swapping and YOU!"
Adventure in baby making!Adv Homes

Warmist

  • Bay Watcher
  • Master of unfinished jobs
    • View Profile
Re: Forcing sieges - a script and research
« Reply #32 on: March 01, 2021, 03:03:14 pm »

Reviving, because fixed the script somewhat:  here

Though see caveats here: here . TL;DR: no guarantees, might brick your save, did only minimal work for this to "work".
Pages: 1 2 [3]