Improve finding sand by using slices
This commit is contained in:
@@ -163,11 +163,9 @@ class MCWorld:
|
||||
return False
|
||||
return True
|
||||
|
||||
def find_sand(self, center, distance, origin):
|
||||
def find_sand(self, center, distance, player):
|
||||
sand = []
|
||||
for i in range(10):
|
||||
check = utils.padd(center, utils.alternate(i, 1))
|
||||
sand.extend(self.find_blocks(check, distance, [blocks.SAND], 20))
|
||||
sand.extend(self.find_blocks(center, distance, [blocks.SAND], 25))
|
||||
|
||||
safe_sand = []
|
||||
for s in sand:
|
||||
@@ -187,9 +185,61 @@ class MCWorld:
|
||||
|
||||
safe_sand.append(s)
|
||||
|
||||
safe_sand.sort(key=lambda x: utils.phyp_bias(center, x, origin))
|
||||
safe_sand.sort(key=lambda x: utils.phyp(player, x))
|
||||
return safe_sand
|
||||
|
||||
def check_sand_slice(self, center):
|
||||
# checks if a 5x5x1 slice has diggable sand in it
|
||||
for i in range(9):
|
||||
s = utils.padd(center, utils.spiral(i))
|
||||
|
||||
if self.block_at(*s) != blocks.SAND:
|
||||
continue
|
||||
# make sure it has solid below
|
||||
if self.block_at(*utils.padd(s, path.BLOCK_BELOW)) in blocks.NON_SOLID_IDS:
|
||||
continue
|
||||
# make sure it has solid two below - prevent hanging sand
|
||||
if self.block_at(*utils.padd(s, path.BLOCK_BELOW2)) in blocks.NON_SOLID_IDS:
|
||||
continue
|
||||
# and walkable air above
|
||||
if self.block_at(*utils.padd(s, path.BLOCK_ABOVE)) not in blocks.NON_SOLID_IDS:
|
||||
continue
|
||||
if not self.sand_adjacent_safe(s):
|
||||
continue
|
||||
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def find_sand_slice(self, center, distance, skip_to=(0, 0)):
|
||||
# returns the centre coord of the next 5x5x1 slice that still has
|
||||
# diggable sand in it. lower slices are only valid if there's an
|
||||
# adjacent slice farther at the same level. this should ensure an
|
||||
# upside down pyramid gets excavated so the edges are still climbable
|
||||
skip_vertical, skip_spiral = skip_to
|
||||
|
||||
for v in count(skip_vertical):
|
||||
peak = utils.padd(center, (0, 20-v, 0))
|
||||
|
||||
layer = 0
|
||||
start_step = skip_spiral if v == skip_vertical else 0
|
||||
for step in count(start_step):
|
||||
offset = utils.spiral(step)
|
||||
layer = max(layer, *offset)
|
||||
offset = utils.pmul(offset, 3)
|
||||
check = utils.padd(peak, offset)
|
||||
check = utils.padd(check, (0, layer, 0))
|
||||
|
||||
if utils.phyp(center, check) >= distance:
|
||||
break
|
||||
|
||||
if self.check_sand_slice(check):
|
||||
return (v-1, step+1), check
|
||||
|
||||
if v > 40:
|
||||
return None, None
|
||||
|
||||
|
||||
def find_bed_openings(self, area):
|
||||
# returns coords in a cardinal direction where we can stand by bed
|
||||
result = []
|
||||
@@ -454,8 +504,23 @@ class Game:
|
||||
|
||||
if command == 'cache':
|
||||
self.g.job.state = self.g.job.cache_items
|
||||
self.g.job.cache_items_states.minimum = 0
|
||||
self.g.job.cache_items_states.silent = True
|
||||
reply = 'ok'
|
||||
|
||||
if command == 'spiral' and data:
|
||||
for i in range(int(data)):
|
||||
print(utils.spiral(i))
|
||||
|
||||
if command == 'sand_slice':
|
||||
try:
|
||||
_, result = self.g.world.find_sand_slice(utils.pint(self.g.pos), 50)
|
||||
reply = str(result)
|
||||
except:
|
||||
import traceback
|
||||
print(traceback.format_exc())
|
||||
reply = 'error'
|
||||
|
||||
if reply:
|
||||
print(reply)
|
||||
if private and not reply.startswith('/'):
|
||||
|
||||
Reference in New Issue
Block a user