New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RDY] Door alignments with TH #1163
Changes from 1 commit
08e5052
6b58abe
b640551
5ecd549
1b06b94
cfac144
be73b26
39d0c43
b25b24c
fa38fca
cef1d2a
b9dbe1b
5f54f55
a0cf7b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1100,7 +1100,11 @@ local window_floor_blueprint_markers = { | |
--!param y (int) Y tile position of the door. | ||
--!param wall (string) Name of the wall (either 'north' or 'west'). | ||
--!param has_swingdoor Whether the room has a normal door (false) or a swing door (true) as entrance. | ||
--!return whether the door can be placed at the given position and orientation. | ||
--!return bit flags indicating invalid tile position using 1 based power of 2 as this works with ipairs | ||
--!values returned are the enumeration of | ||
--! 4 = centre door in swing door or for single door the value can just be non-zero but uses the same bit of code | ||
--! 2 (door section closer to top of screen) - smaller x or y | ||
--! 8 (door section closer to bottom of screen) - larger x or y | ||
local function checkDoorWalls(x, y, wall, has_swingdoor) | ||
local th = TheApp.map.th | ||
|
||
|
@@ -1141,43 +1145,43 @@ local function validDoorTile(xpos, ypos, player_id, world) | |
local th = TheApp.map.th | ||
local tile_flags = th:getCellFlags(xpos, ypos) | ||
-- check builable and own it | ||
if not (tile_flags.buildable or tile_flags.owner == player_id) then return false end | ||
if not tile_flags.buildable and tile_flags.owner ~= player_id then return false end | ||
-- any object will cause it to be blocked (ignore litter) | ||
if not(tile_flags.thob == 0 or tile_flags.thob == 62) then return false end | ||
if tile_flags.thob ~= 0 and tile_flags.thob ~= 62 then return false end | ||
-- check if its passable that no object footprint blocks it | ||
if tile_flags.passable then return world:isTileExclusivelyPassable(xpos, ypos, 1) end | ||
return true | ||
end | ||
|
||
function UIEditRoom:setDoorBlueprint(orig_x, orig_y, orig_wall) | ||
--! Calculate position offsets and door blueprint wall values | ||
--! param x - doors blueprint x value | ||
--! param y - doors blueprint y value | ||
--! param wall - original wall orientation | ||
--! return x - updated x value | ||
--! return y - updated y value | ||
--! return x_mod - offest value to apply to tile count to determine relative position | ||
--! return y_mod - offset value to apply to tile count to determine relatitve position | ||
--! return wall - wall orientation style (only 2 styles) | ||
local function doorWallOffsetCalculations(x, y, wall) | ||
local x_mod | ||
local y_mod | ||
if wall == "south" then | ||
y = y + 1 | ||
wall = "north" | ||
x_mod = 2 | ||
elseif wall == "east" then | ||
x = x + 1 | ||
wall = "west" | ||
y_mod = 2 | ||
elseif wall == "north" then | ||
x_mod = 2 | ||
else | ||
y_mod = 2 | ||
end | ||
return x, y, x_mod, y_mod, wall | ||
--! Calculate position offsets and door blueprint wall values | ||
--! param x - doors blueprint x value | ||
--! param y - doors blueprint y value | ||
--! param wall - original wall orientation | ||
--! return x - updated x value | ||
--! return y - updated y value | ||
--! return x_mod - offest value to apply to tile count to determine relative position | ||
--! return y_mod - offset value to apply to tile count to determine relatitve position | ||
--! return wall - wall orientation style (only 2 styles) | ||
local function doorWallOffsetCalculations(x, y, wall) | ||
local x_mod | ||
local y_mod | ||
if wall == "south" then | ||
y = y + 1 | ||
wall = "north" | ||
x_mod = 2 | ||
elseif wall == "east" then | ||
x = x + 1 | ||
wall = "west" | ||
y_mod = 2 | ||
elseif wall == "north" then | ||
x_mod = 2 | ||
else | ||
y_mod = 2 | ||
end | ||
|
||
return x, y, x_mod, y_mod, wall | ||
end | ||
|
||
function UIEditRoom:setDoorBlueprint(orig_x, orig_y, orig_wall) | ||
local x, y, x_mod, y_mod, wall = doorWallOffsetCalculations(orig_x, orig_y, orig_wall) | ||
local map = TheApp.map.th | ||
|
||
|
@@ -1252,33 +1256,31 @@ function UIEditRoom:setDoorBlueprint(orig_x, orig_y, orig_wall) | |
local world = self.ui.app.world | ||
-- invalid_tile used to select the individual blueprint that is blocked | ||
local invalid_tile = checkDoorWalls(x, y, wall, self.room_type.swing_doors) | ||
self.blueprint_door.valid = invalid_tile == 0 | ||
-- Ensure that the door isn't being built on top of an object | ||
local player_id = self.ui.hospital:getPlayerIndex() | ||
if not validDoorTile(x, y, player_id, world) or | ||
not validDoorTile(x2, y2, player_id, world) then | ||
self.blueprint_door.valid = false | ||
invalid_tile = 4 | ||
invalid_tile = bitOr(invalid_tile, 4) | ||
end | ||
-- If we're making swing doors two more tiles need to be checked. | ||
if self.room_type.swing_doors then | ||
local dx = x_mod and 1 or 0 | ||
local dy = y_mod and 1 or 0 | ||
if not validDoorTile(x + dx, y + dy, player_id, world) or | ||
not validDoorTile(x2 + dx, y2 + dy, player_id, world) then | ||
self.blueprint_door.valid = false | ||
invalid_tile = invalid_tile + 8 | ||
invalid_tile = bitOr(invalid_tile, 8) | ||
end | ||
if not validDoorTile(x - dx, y - dy, player_id, world) or | ||
not validDoorTile(x2 - dx, y2 - dy, player_id, world) then | ||
self.blueprint_door.valid = false | ||
invalid_tile = invalid_tile + 2 | ||
invalid_tile = bitOr(invalid_tile, 2) | ||
end | ||
end | ||
|
||
|
||
self.blueprint_door.valid = (invalid_tile == 0) | ||
|
||
if self.room_type.swing_doors then | ||
for i, animation in ipairs(anim) do | ||
-- calculation here to flag blocked blueprint tiles | ||
-- calculation here to flag blocked blueprint tiles on swing doors for each door tile | ||
animation:setAnimation(self.anims, 126, flags + (hasBit(invalid_tile, i) and 1 or 0) * 16) | ||
end | ||
else | ||
|
@@ -1289,8 +1291,8 @@ function UIEditRoom:setDoorBlueprint(orig_x, orig_y, orig_wall) | |
local dirfix = orig_wall == "east" | ||
flags = dirfix and flags + 1 or flags | ||
for i = 1, 3 do | ||
local x1 = x_mod and orig_x + (i - x_mod) or orig_x | ||
local y1 = y_mod and orig_y + (i - y_mod) or orig_y | ||
local x1 = x_mod and orig_x + i - x_mod or orig_x | ||
local y1 = y_mod and orig_y + i - y_mod or orig_y | ||
if (i == 2) then | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can remove the parentheses on this line. |
||
map:setCell(x1, y1, 4, 24) | ||
else | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -312,10 +312,38 @@ function rangeMapLookup(number, buckets) | |
assert(false) -- Should never get here. | ||
end | ||
|
||
--! Check bit is set | ||
--! param value - value to check set bit of | ||
--! param bit - 0-base index of bit to set 0 - being LSB | ||
function hasBit(value, bit) | ||
local p = 2 ^ bit | ||
return value % (p + p) >= p | ||
end | ||
|
||
|
||
if _G._VERSION == "Lua 5.3" then | ||
-- use builtins 5.3 | ||
function bitOr(value1, value2) | ||
return value1 | value2 | ||
end | ||
|
||
function hasBit(value, bit) | ||
return (value & 2^bit) ~= 0 | ||
end | ||
elseif _G._VERSION == "Lua 5.2" then | ||
-- use builtins 5.2 | ||
function bitOr(value1, value2) | ||
return bit32.bor(value1, value2) | ||
end | ||
|
||
function hasBit(value, bit) | ||
return bit32.btest(value, 2^bit) | ||
end | ||
else | ||
-- this is a pseudo bitwise OR operation | ||
-- assumes value2 is always a power of 2 (limits carry errors in the addition) | ||
-- mimics the logic of hasBit with the addition if bit not set | ||
function bitOr(value1, value2) | ||
return value1 % (value2 + value2) >= value2 and value1 or value1 + value2 | ||
end | ||
--! Check bit is set | ||
--! param value - value to check set bit of | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if it's the cause of the error, but there should be no space between the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have 5.3 supported syntax for the bitwise operators in utility.lua - specifically bitOr and the value1 | value2 Travis still fails as it doesn't use lua 5.3 (yet) - luacheck on utility.lua fails for the same reason, thats not too much more work to build lua in the travis build. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for looking into it! Those changes seem like a prerequisite for this PR, as long as you want to continue using lua 5.3 bitwise operators. It's unfortunate that we can't continue to automatically build and test lua 5.2, as I'm sure compatibility will degrade if it's not used. That said the situations where the latest CorsixTH was available, but only lua 5.2 are likely very close to 0 these days. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I see the issue now. Just my misunderstanding. I could do something like the following for those functions and as long as 5.3 was compiled with compatability on it would use the bit32 stuff, else fall back to the old stuff or just use the old stuff (which is probably the way to go). Just that bitOr routine isn't a real Or - it Ors a single bit only effectively bitOr = bit32 and function(value1, value2) return bit32.bor(value1, value2) end or function(value1, value2) hasBit = bit32 and function(value, bit) return bit32.btest(value, 2^bit) end or function (value, bit) |
||
--! param bit - 0-base index of bit to set 0 - being LSB | ||
function hasBit(value, bit) | ||
local p = 2 ^ bit | ||
return value % (p + p) >= p | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2711,18 +2711,18 @@ end | |
|
||
--[[ When placing doors and objects the passable tiles need to be checked for overlapping | ||
passable tiles. This presents problems with objects like Bench where the passable tile | ||
is not for exclusive use of the Bench (other objects can share that same tile) | ||
the footprint.passthrough differentiates shareable passable tiles, and exclusive use | ||
is not for exclusive use of the Bench (another object can share that same tile) | ||
the footprint.shareable differentiates shareable passable tiles, and exclusive use | ||
passable tiles (the norm for most objects)]] | ||
--! param x - x map tile position | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly there should be no space between |
||
--! param y - y map tile position | ||
--! param distance - searchable distance for nearby objects | ||
--! returns noolean indicating if exclusively passable or not | ||
--! returns boolean indicating if exclusively passable or not | ||
function World:isTileExclusivelyPassable(x, y, distance) | ||
for o in pairs(self:findAllObjectsNear(x, y, distance)) do | ||
if o and o.footprint then | ||
for _, footprint in pairs(o.footprint) do | ||
if footprint[1] + o.tile_x == x and footprint[2] + o.tile_y == y and footprint.only_passable and not footprint.passthrough then | ||
if footprint[1] + o.tile_x == x and footprint[2] + o.tile_y == y and footprint.only_passable and not footprint.shareable then | ||
return false | ||
end | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still pretty sure you actually want not buildable or not owned by the player here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have found a defect with this logic that I will push out.
tile_flags.buildable will be false for every door when a bench footprint 'passable'/shareable tile is in front of the door, it basically only needs to check its owned by the player, as the rest of the code would check the object footprints for built on tiles