Add 3D BFS iterator
This commit is contained in:
@@ -41,6 +41,12 @@ class MCWorld:
|
||||
def block_at(self, x, y, z):
|
||||
return self.g.chunks.get_block_at(x, y, z)
|
||||
|
||||
def find_blocks_3d(self, center, block_ids, distance=0, y_limit=0):
|
||||
for offset in utils.search_3d(distance, y_limit):
|
||||
check = utils.padd(center, offset)
|
||||
if self.block_at(*check) in block_ids:
|
||||
yield check
|
||||
|
||||
def find_blocks(self, center, distance, block_ids, limit=0):
|
||||
# search in a spiral from center to all blocks with ID
|
||||
result = []
|
||||
@@ -112,16 +118,10 @@ class MCWorld:
|
||||
return None
|
||||
|
||||
def find_bed_areas(self, center, distance):
|
||||
air = []
|
||||
for i in range(5):
|
||||
check = utils.padd(center, utils.alternate(i, 1))
|
||||
air.extend(self.find_blocks(check, distance, [0], 0))
|
||||
|
||||
bed_clearance = 25 # 5x5 area
|
||||
clear_distance = 3
|
||||
|
||||
areas = []
|
||||
for a in air:
|
||||
for a in self.find_blocks_3d(center, [0], distance, 10):
|
||||
# check for air around the area
|
||||
if len(self.find_blocks(a, clear_distance, [0], bed_clearance)) < bed_clearance:
|
||||
continue
|
||||
@@ -134,10 +134,7 @@ class MCWorld:
|
||||
if len(self.find_blocks(utils.padd(a, path.BLOCK_ABOVE), clear_distance, [0], bed_clearance)) < bed_clearance:
|
||||
continue
|
||||
|
||||
areas.append(a)
|
||||
|
||||
areas.sort(key=lambda x: utils.phyp(center, x))
|
||||
return areas
|
||||
yield a
|
||||
|
||||
def find_cache_areas(self, center, distance):
|
||||
return self.find_bed_areas(center, distance)
|
||||
@@ -264,15 +261,19 @@ class Game:
|
||||
def handle_chat(self, message):
|
||||
source, text = message
|
||||
reply = None
|
||||
private = False
|
||||
|
||||
if source == 'SYSTEM':
|
||||
print('unlocking command...')
|
||||
self.g.command_lock = False
|
||||
return
|
||||
|
||||
match = re.match(r'<(\w+)> (.*)', text)
|
||||
if match:
|
||||
sender, text = match.groups()
|
||||
match1 = re.match(r'<(\w+)> (.*)', text)
|
||||
match2 = re.match(r'\[(\w+) -> me] (.*)', text)
|
||||
if match1:
|
||||
sender, text = match1.groups()
|
||||
elif match2:
|
||||
sender, text = match2.groups()
|
||||
private = True
|
||||
else:
|
||||
return
|
||||
|
||||
@@ -350,15 +351,12 @@ class Game:
|
||||
reply = 'ok'
|
||||
|
||||
if command == 'inv':
|
||||
print(self.g.inv)
|
||||
inv_list = []
|
||||
for i in self.g.inv.values():
|
||||
if i.present:
|
||||
inv_list.append('{}:{} x {}'.format(items.ITEM_NAMES[i.item_id], str(i.item_id), i.item_count))
|
||||
reply = ', '.join(inv_list)
|
||||
|
||||
if not reply:
|
||||
reply = 'empty'
|
||||
result = '\n'.join(inv_list)
|
||||
print(result or 'Empty')
|
||||
|
||||
if command == 'drop':
|
||||
self.drop_stack()
|
||||
@@ -416,9 +414,16 @@ class Game:
|
||||
if data and v.item_id != int(data): continue
|
||||
print(str(k) + ':', v)
|
||||
|
||||
if command == 'cache':
|
||||
self.g.job.state = self.g.job.cache_items
|
||||
reply = 'ok'
|
||||
|
||||
if reply:
|
||||
print(reply)
|
||||
self.g.chat.send(reply)
|
||||
if private and not reply.startswith('/'):
|
||||
self.g.chat.send('/m ' + sender + ' ' + reply)
|
||||
else:
|
||||
self.g.chat.send(reply)
|
||||
|
||||
def handle_time_update(self, packet):
|
||||
self.g.time = packet.time_of_day % 24000
|
||||
@@ -578,7 +583,7 @@ class Game:
|
||||
def handle_spawn_object(self, packet):
|
||||
#return
|
||||
if packet.type_id != 37: return
|
||||
print(packet)
|
||||
#print(packet)
|
||||
self.g.objects[packet.entity_id] = Munch(
|
||||
entity_id=packet.entity_id,
|
||||
x=packet.x,
|
||||
|
||||
Reference in New Issue
Block a user