Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Browses rooms owned by a unit.
- --[====[
- gui/room-list
- =============
- Activate in :kbd:`q` mode, either immediately or after opening the
- assign owner page.
- .. image:: /docs/images/room-list.png
- The script lists other rooms owned by the same owner, or by the unit
- selected in the assign list, and allows unassigning them.
- ]====]
- local utils = require 'utils'
- local gui = require 'gui'
- local guidm = require 'gui.dwarfmode'
- local room_type_table = {
- [df.building_bedst] = { token = 'bed', tile = 233 },
- [df.building_tablest] = { token = 'table', tile = 209 },
- [df.building_chairst] = { token = 'chair', tile = 210 },
- [df.building_coffinst] = { token = 'coffin', tile = 48 },
- }
- function getRoomName(building, unit)
- local info = room_type_table[building._type]
- if not info or not building.is_room then
- return utils.getBuildingName(building)
- end
- return dfhack.buildings.getRoomDescription(building, unit)
- end
- function makeRoomEntry(bld, unit, is_spouse)
- local info = room_type_table[bld._type] or {}
- return {
- obj = bld,
- token = info.token or '?',
- tile = info.tile or '?',
- caption = getRoomName(bld, unit),
- can_use = (not is_spouse or bld:canUseSpouseRoom()),
- owner = unit
- }
- end
- function listRooms(unit, spouse)
- local rv = {}
- for _,v in pairs(unit.owned_buildings) do
- if v.owner == unit then
- rv[#rv+1] = makeRoomEntry(v, unit, spouse)
- end
- end
- return rv
- end
- function concat_lists(...)
- local rv = {}
- for i = 1,select('#',...) do
- local v = select(i,...)
- if v then
- for _,x in ipairs(v) do rv[#rv+1] = x end
- end
- end
- return rv
- end
- RoomList = defclass(RoomList, guidm.MenuOverlay)
- RoomList.focus_path = 'room-list'
- RoomList.ATTRS{ unit = DEFAULT_NIL }
- function RoomList:init(info)
- local unit = info.unit
- -- local base_bld = df.global.world.selected_building
- self:assign{
- base_building = base_bld,
- items = {}, selected = 1,
- own_rooms = {}, spouse_rooms = {}
- }
- self.old_viewport = self:getViewport()
- self.old_cursor = guidm.getCursorPos()
- if unit then
- self.own_rooms = listRooms(unit)
- self.spouse = df.unit.find(unit.relationship_ids.Spouse)
- if self.spouse then
- self.spouse_rooms = listRooms(self.spouse, unit)
- end
- self.items = concat_lists(self.own_rooms, self.spouse_rooms)
- end
- if base_bld then
- for i,v in ipairs(self.items) do
- if v.obj == base_bld then
- self.selected = i
- v.tile = 26
- goto found
- end
- end
- self.base_item = makeRoomEntry(base_bld, unit)
- self.base_item.owner = unit
- self.base_item.old_owner = base_bld.owner
- self.base_item.tile = 26
- self.items = concat_lists({self.base_item}, self.items)
- ::found::
- end
- end
- local sex_char = { [0] = 12, [1] = 11 }
- function drawUnitName(dc, unit)
- dc:pen(COLOR_GREY)
- if unit then
- local color = dfhack.units.getProfessionColor(unit)
- dc:char(sex_char[unit.sex] or '?'):advance(1):pen(color)
- local vname = dfhack.units.getVisibleName(unit)
- if vname and vname.has_name then
- dc:string(dfhack.TranslateName(vname)..', ')
- end
- dc:string(dfhack.units.getProfessionName(unit))
- else
- dc:string("No Owner Assigned")
- end
- end
- function drawRoomEntry(dc, entry, selected)
- local color = COLOR_GREEN
- if not entry.can_use then
- color = COLOR_RED
- elseif entry.obj.owner ~= entry.owner or not entry.owner then
- color = COLOR_CYAN
- end
- dc:pen{fg = color, bold = (selected == entry)}
- dc:char(entry.tile):advance(1):string(entry.caption)
- end
- function can_modify(sel_item)
- return sel_item and sel_item.owner
- and sel_item.can_use and not sel_item.owner.flags2.killed
- end
- function RoomList:onRenderBody(dc)
- local sel_item = self.items[self.selected]
- dc:clear():seek(1,1)
- drawUnitName(dc, self.unit)
- if self.base_item then
- dc:newline():newline(2)
- drawRoomEntry(dc, self.base_item, sel_item)
- end
- if #self.own_rooms > 0 then
- dc:newline()
- for _,v in ipairs(self.own_rooms) do
- dc:newline(2)
- drawRoomEntry(dc, v, sel_item)
- end
- end
- if #self.spouse_rooms > 0 then
- dc:newline():newline(1)
- drawUnitName(dc, self.spouse)
- dc:newline()
- for _,v in ipairs(self.spouse_rooms) do
- dc:newline(2)
- drawRoomEntry(dc, v, sel_item)
- end
- end
- if self.unit and #self.own_rooms == 0 and #self.spouse_rooms == 0 then
- dc:newline():newline(2):string("No already assigned rooms.", COLOR_LIGHTRED)
- end
- dc:newline():newline(1):pen(COLOR_WHITE)
- dc:key('LEAVESCREEN'):string(": Back")
- if can_modify(sel_item) then
- dc:string(", "):key('SELECT')
- if sel_item.obj.owner == sel_item.owner then
- dc:string(": Unassign")
- else
- dc:string(": Assign")
- end
- end
- dc:newline(1):key_string('LEAVESCREEN_ALL', "Exit to map")
- self:changeSelected(0)
- end
- function RoomList:changeSelected(delta)
- if #self.items < 1 then return end
- self.selected = 1 + (self.selected + delta - 1) % #self.items
- self:selectBuilding(self.items[self.selected].obj)
- end
- function RoomList:onInput(keys)
- local sel_item = self.items[self.selected]
- if keys.SECONDSCROLL_UP then
- self:changeSelected(-1)
- elseif keys.SECONDSCROLL_DOWN then
- self:changeSelected(1)
- elseif keys.LEAVESCREEN or keys.LEAVESCREEN_ALL then
- self:dismiss()
- if keys.LEAVESCREEN_ALL then
- df.global.ui_building_in_assign = false
- elseif self.base_building then
- if not sel_item or self.base_building ~= sel_item.obj then
- self:selectBuilding(self.base_building, self.old_cursor, self.old_viewport)
- end
- if self.unit and self.base_building.owner == self.unit then
- df.global.ui_building_in_assign = false
- end
- end
- elseif keys.SELECT then
- if can_modify(sel_item) then
- local owner = sel_item.owner
- if sel_item.obj.owner == owner then
- owner = sel_item.old_owner
- end
- dfhack.buildings.setOwner(sel_item.obj, owner)
- end
- elseif self:simulateViewScroll(keys) then
- return
- end
- end
- function RoomList:onGetSelectedBuilding()
- return self.items[self.selected].obj
- end
- local focus = dfhack.gui.getCurFocus()
- if focus == 'dwarfmode/QueryBuilding/Some/Assign/Unit' then
- local unit = df.global.ui_building_assign_units[df.global.ui_building_item_cursor]
- RoomList{ unit = unit }:show()
- elseif string.match(dfhack.gui.getCurFocus(), '^dwarfmode/QueryBuilding/Some') then
- local base = df.global.world.selected_building
- RoomList{ unit = base.owner }:show()
- else
- -- 'v' view, 'k' at unit, unit list view
- local unit = dfhack.gui.getSelectedUnit(true)
- if unit then
- RoomList{ unit = unit }:show()
- else
- qerror("This script requires the main dwarfmode view in 'q' mode")
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement