Fix gapple bugs and unload far chunks

master
Tanner Collin 4 years ago
parent 25ce916b43
commit fa9d597483
  1. 11
      bot.py
  2. 6
      game.py
  3. 32
      jobs.py
  4. 24
      protocol/managers.py
  5. 4
      utils.py

@ -51,12 +51,13 @@ def tick(global_state):
target = None
try:
g.chunks.get_block_at(*utils.pint(p))
except ChunkNotLoadedException:
# make sure current chunks are loaded for physics
if not g.chunks.check_loaded(p, 9):
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
#g.jobstate.run()
g.chunks.unload_chunks(p)
if g.path and len(g.path):
target = LPoint3f(g.path[0])
@ -194,7 +195,7 @@ def bot(global_state):
time.sleep(utils.TICK)
print('Player loaded.')
while not g.chunks.check_loaded(g.pos):
while not g.chunks.check_loaded(g.pos, 529):
time.sleep(utils.TICK)
print('Chunks loaded.')

@ -240,11 +240,15 @@ class Game:
print(traceback.format_exc())
def handle_position_and_look(self, packet):
print('pos and look:')
print(packet)
p = LPoint3f(x=packet.x, y=packet.y, z=packet.z)
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):
source, text = message
reply = None

@ -38,15 +38,19 @@ class FindGappleStates:
step = utils.spiral(self.count)
step_scaled = utils.pmul(step, 192)
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)
self.g.chat.send('/tp {} {} {}'.format(*self.coord))
self.g.command_lock = True
self.state = self.wait_for_load
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')
self.state = self.pick_chest
@ -56,9 +60,16 @@ class FindGappleStates:
chest_list.extend(self.g.chunks.index.get(chest_id, []))
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.checked_chests.append(self.current_chest)
self.state = self.break_chest
break
else: # for
@ -68,13 +79,21 @@ class FindGappleStates:
def break_chest(self):
print('Breaking chest', self.current_chest)
self.g.command_lock = True
self.g.item_lock = True
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
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')
self.state = self.pick_chest
@ -95,6 +114,7 @@ class FindGappleStates:
self.coord = None
self.current_chest = None
self.checked_chests = []
self.wait_time = 0
def run(self):
self.state()
@ -602,7 +622,7 @@ class JobStates:
if s1.state == s1.idle:
s1.state = s1.init
elif s1.state == s1.done:
s1.state = s1.init
s1.state = s1.tp_to_coord
s1.run()

@ -1,6 +1,7 @@
import os
from math import floor
import json
import time
from minecraft.networking.packets import clientbound, serverbound
from protocol import packets
@ -112,11 +113,10 @@ class ChunksManager:
if not c: return None
c.set_block_at(x%16, y%16, z%16, block)
def check_loaded(self, position):
#for i in range(441): # TODO: base off render_distance?
def check_loaded(self, position, steps):
x, y, z = utils.pint(position)
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)
check = utils.padd(player_chunk, offset)
@ -125,6 +125,24 @@ class ChunksManager:
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):
def __str__(self):

@ -25,6 +25,10 @@ def phyp_bias(p1, p2, origin):
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
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):
return (floor(p[0]), floor(p[1]), floor(p[2]))

Loading…
Cancel
Save