--[[ Copyright (c) 2009 Peter "Corsix" Cawley Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --]] local object = {} object.id = "door" object.thob = 3 object.name = _S.object.door object.tooltip = _S.tooltip.objects.door object.class = "Door" object.ticks = false object.idle_animations = { north = 104, west = 106, } dofile "queue" class "Door" (Object) function Door:Door(...) self:Object(...) self.queue = Queue() -- Priority should be given to humanoids already inside the door's room, as -- otherwise we could end up in a situation where a patient trying to leave -- a room is in the queue behind a patient trying to enter, and the entering -- one cannot enter until the leaving one has left, etc. self.queue:setPriorityForSameRoom(self) self.hover_cursor = TheApp.gfx:loadMainCursor("queue") -- self.user = "locked" -- prevents doors from being used (debug aid) end function Door:getRoom() return self.room end function Door:updateDynamicInfo() if self.room then self:setDynamicInfo('text', { self.room.room_info.name, _S.dynamic_info.object.queue_size:format(self.queue:reportedSize()), _S.dynamic_info.object.queue_expected:format(self.queue.expected_count) }) end end function Door:onClick(ui, button) -- For consistency with reception desk, only open queue from a left click if button == "left" and self.queue then local queue_window = UIQueue(ui, self.queue) ui:addWindow(queue_window) end end local door_flag_name = { north = {"doorNorth", "tallNorth"}, west = {"doorWest", "tallWest"}, } function Door:setTile(x, y) local map = self.world.map local flag_names = door_flag_name[self.direction] if self.tile_x then map:setCellFlags(self.tile_x, self.tile_y, { [flag_names[1]] = false, [flag_names[2]] = false, buildable = true, doNotIdle = false, }) if self.direction == "west" then map:setCellFlags(self.tile_x - 1, self.tile_y, {buildable = true, doNotIdle = false}) else map:setCellFlags(self.tile_x, self.tile_y - 1, {buildable = true, doNotIdle = false}) end end Object.setTile(self, x, y) if x then map:setCellFlags(x, y, { [flag_names[1]] = true, [flag_names[2]] = true, buildable = false, doNotIdle = true, }) if self.direction == "west" then map:setCellFlags(x - 1, y, {buildable = false, doNotIdle = true}) else map:setCellFlags(x, y - 1, {buildable = false, doNotIdle = true}) end end map.th:updateShadows() return self end function Door:getWalkableTiles() local x, y = self.tile_x, self.tile_y if self.direction == "west" then x = x - 1 else y = y - 1 end return { {self.tile_x, self.tile_y}, {x, y} } end local flag_early_list = 1024 local flag_list_bottom = 2048 function Door:setAnimation(animation, flags) flags = (flags or 0) + flag_list_bottom if self.direction == "north" then flags = flags + flag_early_list end return Object.setAnimation(self, animation, flags) end function Door:closeDoor() self.queue:rerouteAllPatients({name = "seek_room", room_type = self:getRoom().room_info.id}) self:clearDynamicInfo(nil) self.hover_cursor = nil self.queue = nil end function Door:checkForDeadlock() -- In an ideal world, deadlocks should not occur, as they indicate errors in -- some logic elsewhere. From a practical point of view, we should check for -- deadlocks from time to time and attempt to fix them. if self.queue and self.reserved_for then -- If the door is reserved for someone, then that person should either be -- at the front of the queue, or not in any queues at all. for _, action in ipairs(self.reserved_for.action_queue) do if action.name == "queue" then if action.queue ~= self.queue or self.queue[1] ~= self.reserved_for then self.reserved_for = nil self:getRoom():tryAdvanceQueue() end break end end end end return object