Bay 12 Games Forum

Please login or register.

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

Author Topic: What do I need to write this script:  (Read 1804 times)

Roses

  • Bay Watcher
    • View Profile
Re: What do I need to write this script:
« Reply #15 on: November 06, 2017, 04:54:50 pm »

I wrote a script in the past that basically just read the description screen and separated all of the text into different arrays. So you had an array for attributes, thoughts, preferences, beliefs, etc... That way you got out exactly what DF itself would print. The only problem is it is based on color information and ordering, and these things can sometimes change meaning the script would need to be updated for each new DF version. I have included the function below, it may or may not work. Note that this will take either the unit id (not the historical id) or the unit table itself. The last time I tried running it, it gave me output like the ones you see in this post

Code: [Select]
function getInfo(unit)
 local gui = require 'gui'
 local utils = require 'utils'
 local split = utils.split_string
 if tonumber(unit) then
  unit = df.unit.find(tonumber(unit))
 end
 local info = ''
 local info_pars = {}
 local no_color = {}
 local colors = {}
 local information = {}
 information.quote = ''
 information.age = ''
 information.wounds = ''
 information.preferences = ''
 information.attributes = {'',''}
 information.worship = ''
 information.membership = ''
 information.values = ''
 information.thoughts = ''
 information.description = ''
 information.appearance = ''
 information.traits = ''

 game_mode = df.global.gamemode
 if game_mode == 0 then
  gui.simulateInput(dfhack.gui.getCurViewscreen(),'LEAVESCREEN')
  local unitList = {}
  unitList[0] = 'Citizens'
  unitList[1] = 'Livestock'
  unitList[2] = 'Others'
  local temp_screen = df.viewscreen_dwarfmodest:new()
  gui.simulateInput(temp_screen,'D_UNITLIST')
  listScreen = dfhack.gui.getCurViewscreen()
  for page,key in pairs(unitList) do
   for num,unitCheck in pairs(listScreen.units[key]) do
    if unit.id == unitCheck.id then
     x = page
     y = key
     z = num
     break
    end
   end
  end
  if x and y and z then
   listScreen.page = x
   listScreen.cursor_pos[y] = z
   gui.simulateInput(listScreen,'UNITJOB_VIEW_UNIT')
   cur = dfhack.gui.getCurViewscreen()
   gui.simulateInput(listScreen,'LEAVESCREEN')
   if not df.viewscreen_textviewerst:is_instance(cur) then
    gui.simulateInput(cur,'SELECT')
   end
  end
 elseif game_mode == 1 then
  local temp_screen = df.viewscreen_dungeon_monsterstatusst:new()
  temp_screen.unit = tar
  gui.simulateInput(temp_screen,'A_STATUS_DESC')
 end
 
 local read_screen = dfhack.gui.getCurViewscreen()
 if df.viewscreen_textviewerst:is_instance(read_screen) then
 local a_num = 1
 local check = 0
 for i,x in pairs(read_screen.src_text) do
  info = info..' '..x.value
 end
 dfhack.screen.dismiss(read_screen)
 local info_temp = split(info,'%[B%]')
 i = 0
 for k,v in pairs(info_temp) do
  temp = split(v,'%[P%]')
  for l,w in pairs(temp) do
   info_pars[i] = w
   i = i + 1
  end
 end
 for k,v in ipairs(info_pars) do
  no_color[k] = string.gsub(v,"%[C:.:.:.%]","")
  colors[k] = string.sub(v,1,9)
  if string.find(string.sub(v,1,18),"%[C:.:.:.%]",9) then
   colors[k] = string.sub(v,10,18)
  end
 end
 for k,vv in ipairs(no_color) do
  v = info_pars[k]
  if string.find(vv,'"') == 1 then
   information.quote = string.gsub(v,'%[C:.:.:.%]','')
  elseif colors[k] == '[C:3:0:1]' then
   information.worship = string.gsub(v,'%[C:.:.:.%]','')
   check = 1
  elseif colors[k] == '[C:1:0:1]' then
   information.membership = string.gsub(v,'%[C:.:.:.%]','')
   check = 1
  elseif colors[k] == '[C:6:0:1]' then
   information.age = string.gsub(v,'%[C:.:.:.%]','')
   check = 1
  elseif colors[k] == '[C:2:0:0]' or colors[k] == '[C:4:0:0]' then
   information.attributes[a_num] = string.gsub(v,'%[C:.:.:.%]','')
   a_num = a_num + 1
   check = 2
  elseif colors[k] == '[C:2:0:1]' then
   information.preferences = string.gsub(v,'%[C:.:.:.%]','')
   check = 2
  elseif colors[k] == '[C:4:0:1]' then
   information.wounds = string.gsub(v,'%[C:.:.:.%]','')
   check = 1
  elseif (colors[k] == '[C:7:0:0]' or colors[k] == '[C:7:0:1]') and check == 0 then
   information.thoughts = string.gsub(v,'%[C:.:.:.%]','')
   check = 1
  elseif (colors[k] == '[C:7:0:0]' or colors[k] == '[C:7:0:1]') and check == 1 then
   information.appearance = string.gsub(v,'%[C:.:.:.%]','')
   check = 2
  elseif (colors[k] == '[C:7:0:0]' or colors[k] == '[C:7:0:1]') and check == 2 then
   information.values = string.gsub(v,'%[C:.:.:.%]','')
   check = 3
  elseif (colors[k] == '[C:7:0:0]' or colors[k] == '[C:7:0:1]') and check == 3 then
   information.traits = string.gsub(v,'%[C:.:.:.%]','')
   check = 4
  end
 end
 information.description = no_color[#no_color]
 end
 
 return information
end
Logged

PatrikLundell

  • Bay Watcher
    • View Profile
Re: What do I need to write this script:
« Reply #16 on: November 21, 2017, 10:49:56 am »

You may be past that point, but I'm working on a script to do some management of the fortress' members' food preferences for my own usage. The current state collects the food preferences and prints them in an unordered list. It contains a slight improvement to the "thoughts" script for the printout by getting rid of liver, brain, etc. from animals as well as some seed references.
You can obviously use the logic to store all preferences in the summary by removing the condition that it's a LikeFood preference, but the printing part would then have to be changed to print all versions (or be replaced with the desired processing).

Spoiler (click to show/hide)

My eventual goal (which I may well give up on) is to assist in the growing of desired plants beyond booze producing ones to keep their produce in stock without flooding the stocks, plus a list of unavailable stuff that would be desirable to buy from caravans.
I've got a mostly untested version of the production management for booze to build on.

Edit: The merge operation doesn't work as intended as it compares two pointers rather than the items. The first 'if' comparison should be:
      if from_pref.mattype == to_pref.mattype and
         from_pref.matindex == to_pref.matindex then
« Last Edit: November 21, 2017, 12:08:54 pm by PatrikLundell »
Logged
Pages: 1 [2]