Advertisement
user5392

room.lua

Jan 9th, 2019
888
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.41 KB | None | 0 0
  1. -- Browses rooms owned by a unit.
  2. --[====[
  3.  
  4. gui/room-list
  5. =============
  6. Activate in :kbd:`q` mode, either immediately or after opening the
  7. assign owner page.
  8.  
  9. .. image:: /docs/images/room-list.png
  10.  
  11. The script lists other rooms owned by the same owner, or by the unit
  12. selected in the assign list, and allows unassigning them.
  13.  
  14. ]====]
  15. local utils = require 'utils'
  16. local gui = require 'gui'
  17. local guidm = require 'gui.dwarfmode'
  18.  
  19. local room_type_table = {
  20.     [df.building_bedst] = { token = 'bed', tile = 233 },
  21.     [df.building_tablest] = { token = 'table', tile = 209 },
  22.     [df.building_chairst] = { token = 'chair', tile = 210 },
  23.     [df.building_coffinst] = { token = 'coffin', tile = 48 },
  24. }
  25.  
  26. function getRoomName(building, unit)
  27.     local info = room_type_table[building._type]
  28.     if not info or not building.is_room then
  29.         return utils.getBuildingName(building)
  30.     end
  31.     return dfhack.buildings.getRoomDescription(building, unit)
  32. end
  33.  
  34. function makeRoomEntry(bld, unit, is_spouse)
  35.     local info = room_type_table[bld._type] or {}
  36.  
  37.     return {
  38.         obj = bld,
  39.         token = info.token or '?',
  40.         tile = info.tile or '?',
  41.         caption = getRoomName(bld, unit),
  42.         can_use = (not is_spouse or bld:canUseSpouseRoom()),
  43.         owner = unit
  44.     }
  45. end
  46.  
  47. function listRooms(unit, spouse)
  48.     local rv = {}
  49.     for _,v in pairs(unit.owned_buildings) do
  50.         if v.owner == unit then
  51.             rv[#rv+1] = makeRoomEntry(v, unit, spouse)
  52.         end
  53.     end
  54.     return rv
  55. end
  56.  
  57. function concat_lists(...)
  58.     local rv = {}
  59.     for i = 1,select('#',...) do
  60.         local v = select(i,...)
  61.         if v then
  62.             for _,x in ipairs(v) do rv[#rv+1] = x end
  63.         end
  64.     end
  65.     return rv
  66. end
  67.  
  68. RoomList = defclass(RoomList, guidm.MenuOverlay)
  69.  
  70. RoomList.focus_path = 'room-list'
  71.  
  72. RoomList.ATTRS{ unit = DEFAULT_NIL }
  73.  
  74. function RoomList:init(info)
  75.     local unit = info.unit
  76.     -- local base_bld = df.global.world.selected_building
  77.  
  78.     self:assign{
  79.         base_building = base_bld,
  80.         items = {}, selected = 1,
  81.         own_rooms = {}, spouse_rooms = {}
  82.     }
  83.  
  84.     self.old_viewport = self:getViewport()
  85.     self.old_cursor = guidm.getCursorPos()
  86.  
  87.     if unit then
  88.         self.own_rooms = listRooms(unit)
  89.         self.spouse = df.unit.find(unit.relationship_ids.Spouse)
  90.         if self.spouse then
  91.             self.spouse_rooms = listRooms(self.spouse, unit)
  92.         end
  93.         self.items = concat_lists(self.own_rooms, self.spouse_rooms)
  94.     end
  95.  
  96.     if base_bld then
  97.         for i,v in ipairs(self.items) do
  98.             if v.obj == base_bld then
  99.                 self.selected = i
  100.                 v.tile = 26
  101.                 goto found
  102.             end
  103.         end
  104.         self.base_item = makeRoomEntry(base_bld, unit)
  105.         self.base_item.owner = unit
  106.         self.base_item.old_owner = base_bld.owner
  107.         self.base_item.tile = 26
  108.         self.items = concat_lists({self.base_item}, self.items)
  109.     ::found::
  110.     end
  111. end
  112.  
  113. local sex_char = { [0] = 12, [1] = 11 }
  114.  
  115. function drawUnitName(dc, unit)
  116.     dc:pen(COLOR_GREY)
  117.     if unit then
  118.         local color = dfhack.units.getProfessionColor(unit)
  119.         dc:char(sex_char[unit.sex] or '?'):advance(1):pen(color)
  120.  
  121.         local vname = dfhack.units.getVisibleName(unit)
  122.         if vname and vname.has_name then
  123.             dc:string(dfhack.TranslateName(vname)..', ')
  124.         end
  125.         dc:string(dfhack.units.getProfessionName(unit))
  126.     else
  127.         dc:string("No Owner Assigned")
  128.     end
  129. end
  130.  
  131. function drawRoomEntry(dc, entry, selected)
  132.     local color = COLOR_GREEN
  133.     if not entry.can_use then
  134.         color = COLOR_RED
  135.     elseif entry.obj.owner ~= entry.owner or not entry.owner then
  136.         color = COLOR_CYAN
  137.     end
  138.     dc:pen{fg = color, bold = (selected == entry)}
  139.     dc:char(entry.tile):advance(1):string(entry.caption)
  140. end
  141.  
  142. function can_modify(sel_item)
  143.     return sel_item and sel_item.owner
  144.        and sel_item.can_use and not sel_item.owner.flags2.killed
  145. end
  146.  
  147. function RoomList:onRenderBody(dc)
  148.     local sel_item = self.items[self.selected]
  149.  
  150.     dc:clear():seek(1,1)
  151.     drawUnitName(dc, self.unit)
  152.  
  153.     if self.base_item then
  154.         dc:newline():newline(2)
  155.         drawRoomEntry(dc, self.base_item, sel_item)
  156.     end
  157.     if #self.own_rooms > 0 then
  158.         dc:newline()
  159.         for _,v in ipairs(self.own_rooms) do
  160.             dc:newline(2)
  161.             drawRoomEntry(dc, v, sel_item)
  162.         end
  163.     end
  164.     if #self.spouse_rooms > 0 then
  165.         dc:newline():newline(1)
  166.         drawUnitName(dc, self.spouse)
  167.  
  168.         dc:newline()
  169.         for _,v in ipairs(self.spouse_rooms) do
  170.             dc:newline(2)
  171.             drawRoomEntry(dc, v, sel_item)
  172.         end
  173.     end
  174.     if self.unit and #self.own_rooms == 0 and #self.spouse_rooms == 0 then
  175.         dc:newline():newline(2):string("No already assigned rooms.", COLOR_LIGHTRED)
  176.     end
  177.  
  178.     dc:newline():newline(1):pen(COLOR_WHITE)
  179.     dc:key('LEAVESCREEN'):string(": Back")
  180.  
  181.     if can_modify(sel_item) then
  182.         dc:string(", "):key('SELECT')
  183.         if sel_item.obj.owner == sel_item.owner then
  184.             dc:string(": Unassign")
  185.         else
  186.             dc:string(": Assign")
  187.         end
  188.     end
  189.  
  190.     dc:newline(1):key_string('LEAVESCREEN_ALL', "Exit to map")
  191.     self:changeSelected(0)
  192. end
  193.  
  194. function RoomList:changeSelected(delta)
  195.     if #self.items < 1 then return end
  196.     self.selected = 1 + (self.selected + delta - 1) % #self.items
  197.     self:selectBuilding(self.items[self.selected].obj)
  198. end
  199.  
  200. function RoomList:onInput(keys)
  201.     local sel_item = self.items[self.selected]
  202.  
  203.     if keys.SECONDSCROLL_UP then
  204.         self:changeSelected(-1)
  205.     elseif keys.SECONDSCROLL_DOWN then
  206.         self:changeSelected(1)
  207.     elseif keys.LEAVESCREEN or keys.LEAVESCREEN_ALL then
  208.         self:dismiss()
  209.  
  210.         if keys.LEAVESCREEN_ALL then
  211.             df.global.ui_building_in_assign = false
  212.         elseif self.base_building then
  213.             if not sel_item or self.base_building ~= sel_item.obj then
  214.                 self:selectBuilding(self.base_building, self.old_cursor, self.old_viewport)
  215.             end
  216.             if self.unit and self.base_building.owner == self.unit then
  217.                 df.global.ui_building_in_assign = false
  218.             end
  219.         end
  220.     elseif keys.SELECT then
  221.         if can_modify(sel_item) then
  222.             local owner = sel_item.owner
  223.             if sel_item.obj.owner == owner then
  224.                 owner = sel_item.old_owner
  225.             end
  226.             dfhack.buildings.setOwner(sel_item.obj, owner)
  227.         end
  228.     elseif self:simulateViewScroll(keys) then
  229.         return
  230.     end
  231. end
  232.  
  233. function RoomList:onGetSelectedBuilding()
  234.     return self.items[self.selected].obj
  235. end
  236.  
  237. local focus = dfhack.gui.getCurFocus()
  238.  
  239. if focus == 'dwarfmode/QueryBuilding/Some/Assign/Unit' then
  240.     local unit = df.global.ui_building_assign_units[df.global.ui_building_item_cursor]
  241.     RoomList{ unit = unit }:show()
  242. elseif string.match(dfhack.gui.getCurFocus(), '^dwarfmode/QueryBuilding/Some') then
  243.     local base = df.global.world.selected_building
  244.     RoomList{ unit = base.owner }:show()
  245. else
  246.        -- 'v' view, 'k' at unit, unit list view
  247.     local unit = dfhack.gui.getSelectedUnit(true)
  248.     if unit then
  249.         RoomList{ unit = unit }:show()
  250.     else
  251.         qerror("This script requires the main dwarfmode view in 'q' mode")
  252.     end
  253. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement