Fix gapple bugs and unload far chunks

This commit is contained in:
Tanner Collin 2020-09-25 15:51:36 -06:00
parent 25ce916b43
commit fa9d597483
5 changed files with 62 additions and 15 deletions

11
bot.py
View File

@ -51,12 +51,13 @@ def tick(global_state):
target = None target = None
try: # make sure current chunks are loaded for physics
g.chunks.get_block_at(*utils.pint(p)) if not g.chunks.check_loaded(p, 9):
except ChunkNotLoadedException: packet = serverbound.play.PositionAndLookPacket(x=p.x, feet_y=p.y, z=p.z, pitch=0, yaw=0, on_ground=True)
g.connection.write_packet(packet, force=True)
return return
#g.jobstate.run() g.chunks.unload_chunks(p)
if g.path and len(g.path): if g.path and len(g.path):
target = LPoint3f(g.path[0]) target = LPoint3f(g.path[0])
@ -194,7 +195,7 @@ def bot(global_state):
time.sleep(utils.TICK) time.sleep(utils.TICK)
print('Player loaded.') print('Player loaded.')
while not g.chunks.check_loaded(g.pos): while not g.chunks.check_loaded(g.pos, 529):
time.sleep(utils.TICK) time.sleep(utils.TICK)
print('Chunks loaded.') print('Chunks loaded.')

View File

@ -240,11 +240,15 @@ class Game:
print(traceback.format_exc()) print(traceback.format_exc())
def handle_position_and_look(self, packet): def handle_position_and_look(self, packet):
print('pos and look:')
print(packet) print(packet)
p = LPoint3f(x=packet.x, y=packet.y, z=packet.z) p = LPoint3f(x=packet.x, y=packet.y, z=packet.z)
self.g.pos = p self.g.pos = p
confirm_packet = serverbound.play.TeleportConfirmPacket()
confirm_packet.teleport_id = packet.teleport_id
self.g.connection.write_packet(confirm_packet)
def handle_chat(self, message): def handle_chat(self, message):
source, text = message source, text = message
reply = None reply = None

32
jobs.py
View File

@ -38,15 +38,19 @@ class FindGappleStates:
step = utils.spiral(self.count) step = utils.spiral(self.count)
step_scaled = utils.pmul(step, 192) step_scaled = utils.pmul(step, 192)
self.coord = utils.padd(self.origin, step_scaled) self.coord = utils.padd(self.origin, step_scaled)
self.coord = utils.padd(self.coord, (0, 50, 0)) self.coord = (self.coord[0], 50, self.coord[2])
print('count:', self.count, 'teleporting to:', self.coord) print('count:', self.count, 'teleporting to:', self.coord)
self.g.chat.send('/tp {} {} {}'.format(*self.coord)) self.g.chat.send('/tp {} {} {}'.format(*self.coord))
self.g.command_lock = True
self.state = self.wait_for_load self.state = self.wait_for_load
def wait_for_load(self): def wait_for_load(self):
if self.g.chunks.check_loaded(self.g.pos): if self.g.command_lock:
return
if self.g.chunks.check_loaded(self.g.pos, 169):
print('chunks have been loaded') print('chunks have been loaded')
self.state = self.pick_chest self.state = self.pick_chest
@ -56,9 +60,16 @@ class FindGappleStates:
chest_list.extend(self.g.chunks.index.get(chest_id, [])) chest_list.extend(self.g.chunks.index.get(chest_id, []))
for chest in chest_list: for chest in chest_list:
if chest in self.checked_chests: continue if chest in self.checked_chests:
# slow but simple
continue
if utils.phyp_king(self.coord, chest) > 96:
# skip because we can't detect item drops
continue
self.current_chest = chest self.current_chest = chest
self.checked_chests.append(self.current_chest)
self.state = self.break_chest self.state = self.break_chest
break break
else: # for else: # for
@ -68,13 +79,21 @@ class FindGappleStates:
def break_chest(self): def break_chest(self):
print('Breaking chest', self.current_chest) print('Breaking chest', self.current_chest)
self.g.command_lock = True self.g.command_lock = True
self.g.item_lock = True
self.g.chat.send('/setblock {} {} {} air destroy'.format(*self.current_chest)) self.g.chat.send('/setblock {} {} {} air destroy'.format(*self.current_chest))
self.checked_chests.append(self.current_chest)
self.wait_time = 0.5
self.state = self.wait_for_items self.state = self.wait_for_items
def wait_for_items(self): def wait_for_items(self):
if not self.g.command_lock: # wait for command to execute
if self.g.command_lock:
return
# wait for items to drop
if self.wait_time > 0:
self.wait_time -= utils.TICK
else:
print('done waiting for items') print('done waiting for items')
self.state = self.pick_chest self.state = self.pick_chest
@ -95,6 +114,7 @@ class FindGappleStates:
self.coord = None self.coord = None
self.current_chest = None self.current_chest = None
self.checked_chests = [] self.checked_chests = []
self.wait_time = 0
def run(self): def run(self):
self.state() self.state()
@ -602,7 +622,7 @@ class JobStates:
if s1.state == s1.idle: if s1.state == s1.idle:
s1.state = s1.init s1.state = s1.init
elif s1.state == s1.done: elif s1.state == s1.done:
s1.state = s1.init s1.state = s1.tp_to_coord
s1.run() s1.run()

View File

@ -1,6 +1,7 @@
import os import os
from math import floor from math import floor
import json import json
import time
from minecraft.networking.packets import clientbound, serverbound from minecraft.networking.packets import clientbound, serverbound
from protocol import packets from protocol import packets
@ -112,11 +113,10 @@ class ChunksManager:
if not c: return None if not c: return None
c.set_block_at(x%16, y%16, z%16, block) c.set_block_at(x%16, y%16, z%16, block)
def check_loaded(self, position): def check_loaded(self, position, steps):
#for i in range(441): # TODO: base off render_distance?
x, y, z = utils.pint(position) x, y, z = utils.pint(position)
player_chunk = (x//16, 1, z//16) player_chunk = (x//16, 1, z//16)
for i in range(121): # TODO: base off render_distance? for i in range(steps): # TODO: base off render_distance?
offset = utils.spiral(i) offset = utils.spiral(i)
check = utils.padd(player_chunk, offset) check = utils.padd(player_chunk, offset)
@ -125,6 +125,24 @@ class ChunksManager:
return True return True
def unload_chunks(self, position):
start = time.time()
x, y, z = utils.pint(position)
player_chunk = (x//16, 0, z//16)
loaded_chunks = list(self.chunks.keys())
count = 0
for chunk in loaded_chunks:
check = (chunk[0], 0, chunk[2])
if utils.phyp_king(player_chunk, check) > 16:
del self.chunks[chunk]
count += 1
if count:
print('unloaded', count, 'chunks in', time.time()-start, 's')
class ChunkNotLoadedException(Exception): class ChunkNotLoadedException(Exception):
def __str__(self): def __str__(self):

View File

@ -25,6 +25,10 @@ def phyp_bias(p1, p2, origin):
height_diff = height_diff*8 if height_diff < 0 else height_diff*0.5 height_diff = height_diff*8 if height_diff < 0 else height_diff*0.5
return hypot(p1[0] - p2[0], height_diff, p1[2] - p2[2]) + origin_distance*0.5 return hypot(p1[0] - p2[0], height_diff, p1[2] - p2[2]) + origin_distance*0.5
def phyp_king(p1, p2):
# calculates the Chebyshev distance
return max(abs(p1[0] - p2[0]), abs(p1[1] - p2[1]), abs(p1[2] - p2[2]))
def pint(p): def pint(p):
return (floor(p[0]), floor(p[1]), floor(p[2])) return (floor(p[0]), floor(p[1]), floor(p[2]))