Implement 26.3 bed sleeping
This commit is contained in:
+46
-26
@@ -158,28 +158,50 @@ class World:
|
||||
return navpath
|
||||
|
||||
def find_bed_areas(self, center, distance):
|
||||
bed_clearance = 9 # 5x5 area
|
||||
clear_distance = 2
|
||||
|
||||
for a in self.find_blocks_3d(center, [0], distance, 50):
|
||||
# check for air around the area
|
||||
if len(self.find_blocks(a, clear_distance, [0], bed_clearance)) < bed_clearance:
|
||||
"""Yield nearby two-block bed footprints on solid, safe ground."""
|
||||
# Only search loaded-neighborhood distance. The old 3-D flood fill
|
||||
# explored millions of air blocks and used overly broad 5x5 clearance.
|
||||
distance = min(distance, 32)
|
||||
headroom = path.BLOCK_ABOVE
|
||||
support = path.BLOCK_BELOW
|
||||
for offset in utils.search_2d(distance):
|
||||
if utils.hypot(offset[0], offset[2]) > distance:
|
||||
continue
|
||||
for dy in (0, 1, -1, 2, -2):
|
||||
area = (center[0] + offset[0], center[1] + dy,
|
||||
center[2] + offset[2])
|
||||
if area == center:
|
||||
continue
|
||||
if self.block_at(*area) != blocks.AIR:
|
||||
continue
|
||||
if self.block_at(*utils.padd(area, headroom)) != blocks.AIR:
|
||||
continue
|
||||
support_block = self.block_at(*utils.padd(area, support))
|
||||
if (support_block is None or
|
||||
support_block in blocks.NON_SOLID_IDS or
|
||||
support_block in blocks.AVOID_IDS):
|
||||
continue
|
||||
|
||||
# check for ground around the area
|
||||
if len(self.find_blocks(utils.padd(a, path.BLOCK_BELOW), clear_distance, blocks.NON_SOLID_IDS, bed_clearance)):
|
||||
continue
|
||||
footprint_found = False
|
||||
for direction in path.CHECK_DIRECTIONS:
|
||||
head = utils.padd(area, direction)
|
||||
if (self.block_at(*head) != blocks.AIR or
|
||||
self.block_at(*utils.padd(head, headroom)) != blocks.AIR):
|
||||
continue
|
||||
head_support = self.block_at(*utils.padd(head, support))
|
||||
if (head_support is None or
|
||||
head_support in blocks.NON_SOLID_IDS or
|
||||
head_support in blocks.AVOID_IDS):
|
||||
continue
|
||||
footprint_found = True
|
||||
break
|
||||
if not footprint_found:
|
||||
continue
|
||||
|
||||
# check for air above the area
|
||||
if len(self.find_blocks(utils.padd(a, path.BLOCK_ABOVE), clear_distance, [0], bed_clearance)) < bed_clearance:
|
||||
continue
|
||||
|
||||
# ensure there's no monsters within 20 blocks
|
||||
# can't sleep if they are within 10, good to have a buffer
|
||||
if self.find_monsters(a, 20):
|
||||
continue
|
||||
|
||||
yield a
|
||||
# Avoid placing a bed within range of nearby monsters.
|
||||
if self.find_monsters(area, 20):
|
||||
continue
|
||||
yield area
|
||||
|
||||
def find_cache_areas(self, center, distance):
|
||||
"""Yield nearby, supported air blocks suitable for placing a chest."""
|
||||
@@ -294,14 +316,12 @@ class World:
|
||||
return result
|
||||
|
||||
def check_bed_occupied(self, bed):
|
||||
# returns true if the bed is occupied by a player
|
||||
"""Return whether a loaded bed block currently has occupied=true."""
|
||||
bid = self.g.chunks.get_block_at(*bed)
|
||||
if blocks.PROPS[bid]['occupied'] == 'true':
|
||||
print('Checking bed occupancy:', bed, '-> occupied')
|
||||
return True
|
||||
else:
|
||||
print('Checking bed occupancy:', bed, '-> free')
|
||||
return False
|
||||
occupied = blocks.PROPS.get(bid, {}).get('occupied') == 'true'
|
||||
print('Checking bed occupancy:', bed, '->',
|
||||
'occupied' if occupied else 'free')
|
||||
return occupied
|
||||
|
||||
def find_cache_openings(self, area):
|
||||
return self.find_bed_openings(area)
|
||||
|
||||
Reference in New Issue
Block a user