Grab fallen saplings, fix bugs

This commit is contained in:
Tanner Collin 2020-10-15 01:37:47 -06:00
parent f328f3443a
commit 6c4aaf8d7d
5 changed files with 104 additions and 56 deletions

3
bot.py
View File

@ -6,6 +6,7 @@ import os
import time import time
import importlib import importlib
from math import floor, ceil from math import floor, ceil
from copy import copy
USERNAME = os.environ['USERNAME'] USERNAME = os.environ['USERNAME']
PASSWORD = os.environ['PASSWORD'] PASSWORD = os.environ['PASSWORD']
@ -61,7 +62,7 @@ def tick(global_state):
########## object physics ########## ########## object physics ##########
for eid, obj in g.objects.items(): for eid, obj in copy(g.objects).items():
start_x = obj.x start_x = obj.x
if obj.velocity_x: if obj.velocity_x:

35
game.py
View File

@ -5,6 +5,7 @@ import random
from math import hypot from math import hypot
from itertools import count from itertools import count
from munch import Munch from munch import Munch
from copy import copy
from panda3d.core import LPoint3f from panda3d.core import LPoint3f
@ -12,13 +13,12 @@ from minecraft.networking.packets import Packet, clientbound, serverbound
from minecraft.networking.types import BlockFace from minecraft.networking.types import BlockFace
from protocol.packets import ( from protocol.packets import (
TimeUpdatePacket, SetSlotPacket, PlayerDiggingPacket, SetSlotPacket, PlayerDiggingPacket,
BlockBreakAnimationPacket, AcknowledgePlayerDiggingPacket, BlockBreakAnimationPacket, AcknowledgePlayerDiggingPacket,
HeldItemChangePacket, PickItemPacket, OpenWindowPacket, HeldItemChangePacket, PickItemPacket, OpenWindowPacket,
ClickWindowPacket, CloseWindowPacket, ServerWindowConfirmationPacket, ClickWindowPacket, CloseWindowPacket, ServerWindowConfirmationPacket,
ClientWindowConfirmationPacket, EntityMetadataPacket, ClientWindowConfirmationPacket, EntityMetadataPacket,
SpawnLivingEntityPacket, EntityPositionPacket, SpawnLivingEntityPacket, EntityPositionRotationPacket, DestroyEntitiesPacket,
EntityPositionRotationPacket, DestroyEntitiesPacket, EntityVelocityPacket,
) )
from protocol.types import Slot from protocol.types import Slot
@ -115,20 +115,23 @@ class MCWorld:
air = [] air = []
for i in range(5): for i in range(5):
check = utils.padd(center, utils.alternate(i, 1)) check = utils.padd(center, utils.alternate(i, 1))
air.extend(self.find_blocks(check, distance, [0], 200)) air.extend(self.find_blocks(check, distance, [0], 0))
bed_clearance = 25 # 5x5 area
clear_distance = 3
areas = [] areas = []
for a in air: for a in air:
# check for ground around the area # check for air around the area
if len(self.find_blocks(utils.padd(a, path.BLOCK_BELOW), 2, blocks.NON_SOLID_IDS, 9)): if len(self.find_blocks(a, clear_distance, [0], bed_clearance)) < bed_clearance:
continue continue
# check for air around the area # check for ground around the area
if len(self.find_blocks(a, 2, [0], 9)) < 9: if len(self.find_blocks(utils.padd(a, path.BLOCK_BELOW), clear_distance, blocks.NON_SOLID_IDS, bed_clearance)):
continue continue
# check for air above the area # check for air above the area
if len(self.find_blocks(utils.padd(a, path.BLOCK_ABOVE), 2, [0], 9)) < 9: if len(self.find_blocks(utils.padd(a, path.BLOCK_ABOVE), clear_distance, [0], bed_clearance)) < bed_clearance:
continue continue
areas.append(a) areas.append(a)
@ -183,6 +186,13 @@ class MCWorld:
def find_cache_openings(self, area): def find_cache_openings(self, area):
return self.find_bed_openings(area) return self.find_bed_openings(area)
def find_objects(self, object_ids):
result = []
for eid, obj in copy(self.g.objects).items():
if obj.get('item_id', None) in object_ids:
result.append(obj)
return result
class Game: class Game:
def __init__(self, global_state): def __init__(self, global_state):
@ -192,7 +202,7 @@ class Game:
register(self.handle_block_change, clientbound.play.BlockChangePacket) register(self.handle_block_change, clientbound.play.BlockChangePacket)
register(self.handle_join_game, clientbound.play.JoinGamePacket) register(self.handle_join_game, clientbound.play.JoinGamePacket)
register(self.handle_position_and_look, clientbound.play.PlayerPositionAndLookPacket) register(self.handle_position_and_look, clientbound.play.PlayerPositionAndLookPacket)
register(self.handle_time_update, TimeUpdatePacket) register(self.handle_time_update, clientbound.play.TimeUpdatePacket)
register(self.handle_set_slot, SetSlotPacket) register(self.handle_set_slot, SetSlotPacket)
register(self.handle_break_animation, BlockBreakAnimationPacket) register(self.handle_break_animation, BlockBreakAnimationPacket)
register(self.handle_break_ack, AcknowledgePlayerDiggingPacket) register(self.handle_break_ack, AcknowledgePlayerDiggingPacket)
@ -201,10 +211,10 @@ class Game:
register(self.handle_spawn_object, clientbound.play.SpawnObjectPacket) register(self.handle_spawn_object, clientbound.play.SpawnObjectPacket)
register(self.handle_entity_metadata, EntityMetadataPacket) register(self.handle_entity_metadata, EntityMetadataPacket)
register(self.handle_spawn_living, SpawnLivingEntityPacket) register(self.handle_spawn_living, SpawnLivingEntityPacket)
register(self.handle_entity_position, EntityPositionPacket) register(self.handle_entity_position, clientbound.play.EntityPositionDeltaPacket)
register(self.handle_entity_position_rotation, EntityPositionRotationPacket) register(self.handle_entity_position_rotation, EntityPositionRotationPacket)
register(self.handle_destroy_entities, DestroyEntitiesPacket) register(self.handle_destroy_entities, DestroyEntitiesPacket)
register(self.handle_entity_velocity, EntityVelocityPacket) #register(self.handle_entity_velocity, clientbound.play.EntityVelocityPacket)
#register(self.handle_packet, Packet, early=True) #register(self.handle_packet, Packet, early=True)
@ -570,6 +580,7 @@ class Game:
if packet.type_id != 37: return if packet.type_id != 37: return
print(packet) print(packet)
self.g.objects[packet.entity_id] = Munch( self.g.objects[packet.entity_id] = Munch(
entity_id=packet.entity_id,
x=packet.x, x=packet.x,
y=packet.y, y=packet.y,
z=packet.z, z=packet.z,

81
jobs.py
View File

@ -1,6 +1,7 @@
import re import re
import time import time
import importlib import importlib
import random
from math import hypot from math import hypot
from panda3d.core import LPoint3f from panda3d.core import LPoint3f
@ -626,8 +627,6 @@ class PlantTreeStates:
def idle(self): def idle(self):
return None return None
# TODO: maybe add a "plant deficit" so we know when to plant or not
def init(self): def init(self):
if self.g.chopped_tree: if self.g.chopped_tree:
self.state = self.check_feet self.state = self.check_feet
@ -731,6 +730,75 @@ class PlantTreeStates:
self.state() self.state()
class GrabSaplingStates:
def idle(self):
return None
def init(self):
self.state = self.find_saplings
print('Trying to grab a sapling')
def find_saplings(self):
w = self.g.world
saplings = w.find_objects(items.SAPLING_IDS)
if not saplings:
print('No saplings objects found, aborting')
self.state = self.cleanup
return
random.shuffle(saplings)
for s in saplings:
p = utils.pint(self.g.pos)
s_pos = utils.pint((s.x, s.y, s.z))
check = utils.padd(s_pos, path.BLOCK_BELOW)
if s.entity_id in self.eid_blacklist:
continue
# slip if the sapling is floating
if self.g.chunks.get_block_at(*check) in blocks.LEAF_IDS | {0}:
continue
navpath = w.path_to_place(p, s_pos)
if navpath:
self.g.path = navpath
self.state = self.going_to_sapling
self.sapling = s_pos
self.eid_blacklist.append(s.entity_id)
print('Going to sapling', self.sapling)
return
print('Cant get to any saplings, aborting')
self.state = self.cleanup
def going_to_sapling(self):
if utils.pint(self.g.pos) == self.sapling:
self.state = self.cleanup
def cleanup(self):
self.g.look_at = None
self.state = self.done
def done(self):
# never gets ran, placeholder
return None
def __init__(self, global_state):
self.g = global_state
self.state = self.idle
self.sapling = None
self.eid_blacklist = []
def run(self):
self.state()
class JobStates: class JobStates:
def idle(self): def idle(self):
return None return None
@ -802,12 +870,14 @@ class JobStates:
s2 = self.plant_tree_states s2 = self.plant_tree_states
s3 = self.sleep_with_bed_states s3 = self.sleep_with_bed_states
s4 = self.cache_items_states s4 = self.cache_items_states
s5 = self.grab_sapling_states
if s1.state == s1.idle: if s1.state == s1.idle:
s1.state = s1.init s1.state = s1.init
s2.state = s2.init s2.state = s2.init
s3.state = s3.init s3.state = s3.init
s4.state = s4.init s4.state = s4.init
s5.state = s5.init
elif s1.state == s1.done: elif s1.state == s1.done:
if s2.state != s2.done: if s2.state != s2.done:
s2.run() s2.run()
@ -821,10 +891,15 @@ class JobStates:
s4.run() s4.run()
return return
if s5.state != s5.done:
s5.run()
return
s1.state = s1.init s1.state = s1.init
s2.state = s2.init s2.state = s2.init
s3.state = s3.init s3.state = s3.init
s4.state = s4.init s4.state = s4.init
s5.state = s5.init
return return
s1.run() s1.run()
@ -836,6 +911,7 @@ class JobStates:
self.cache_items_states = CacheItemsStates(self.g) self.cache_items_states = CacheItemsStates(self.g)
self.find_gapple_states = FindGappleStates(self.g) self.find_gapple_states = FindGappleStates(self.g)
self.plant_tree_states = PlantTreeStates(self.g) self.plant_tree_states = PlantTreeStates(self.g)
self.grab_sapling_states = GrabSaplingStates(self.g)
self.state = self.idle self.state = self.idle
def __init__(self, global_state): def __init__(self, global_state):
@ -849,6 +925,7 @@ class JobStates:
self.cache_items_states = CacheItemsStates(self.g) self.cache_items_states = CacheItemsStates(self.g)
self.find_gapple_states = FindGappleStates(self.g) self.find_gapple_states = FindGappleStates(self.g)
self.plant_tree_states = PlantTreeStates(self.g) self.plant_tree_states = PlantTreeStates(self.g)
self.grab_sapling_states = GrabSaplingStates(self.g)
def tick(self): def tick(self):
self.state() self.state()

View File

@ -11,7 +11,6 @@ def get_packets(old_get_packets):
mc_packets.add(packets.AcknowledgePlayerDiggingPacket) mc_packets.add(packets.AcknowledgePlayerDiggingPacket)
mc_packets.add(packets.BlockBreakAnimationPacket) mc_packets.add(packets.BlockBreakAnimationPacket)
mc_packets.add(packets.SetSlotPacket) mc_packets.add(packets.SetSlotPacket)
mc_packets.add(packets.TimeUpdatePacket)
mc_packets.add(packets.PlayerDiggingPacket) mc_packets.add(packets.PlayerDiggingPacket)
mc_packets.add(packets.PickItemPacket) mc_packets.add(packets.PickItemPacket)
mc_packets.add(packets.HeldItemChangePacket) mc_packets.add(packets.HeldItemChangePacket)
@ -22,10 +21,8 @@ def get_packets(old_get_packets):
mc_packets.add(packets.ServerWindowConfirmationPacket) mc_packets.add(packets.ServerWindowConfirmationPacket)
mc_packets.add(packets.EntityMetadataPacket) mc_packets.add(packets.EntityMetadataPacket)
mc_packets.add(packets.SpawnLivingEntityPacket) mc_packets.add(packets.SpawnLivingEntityPacket)
mc_packets.add(packets.EntityPositionPacket)
mc_packets.add(packets.EntityPositionRotationPacket) mc_packets.add(packets.EntityPositionRotationPacket)
mc_packets.add(packets.DestroyEntitiesPacket) mc_packets.add(packets.DestroyEntitiesPacket)
mc_packets.add(packets.EntityVelocityPacket)
return mc_packets return mc_packets
return lambda x: wrapper(old_get_packets, x) return lambda x: wrapper(old_get_packets, x)

View File

@ -174,15 +174,6 @@ class SetSlotPacket(Packet):
] ]
class TimeUpdatePacket(Packet):
id = 0x4E
packet_name = 'time update'
definition = [
{'world_age': Long},
{'time_of_day': Long},
]
class PlayerDiggingPacket(Packet): class PlayerDiggingPacket(Packet):
# used when player mines / breaks blocks # used when player mines / breaks blocks
# https://wiki.vg/Protocol#Player_Digging # https://wiki.vg/Protocol#Player_Digging
@ -339,21 +330,6 @@ class SpawnLivingEntityPacket(Packet):
{'velocity_z': Short}, {'velocity_z': Short},
] ]
class EntityPositionPacket(Packet):
# Sent by the server when an entity moves less then 8 blocks
# https://wiki.vg/Protocol#Spawn_Entity
id = 0x27
packet_name = 'entity position'
definition = [
{'entity_id': VarInt},
{'delta_x': Short},
{'delta_y': Short},
{'delta_z': Short},
{'on_ground': Boolean},
]
class EntityPositionRotationPacket(Packet): class EntityPositionRotationPacket(Packet):
# Sent by the server when an entity rotates and moves # Sent by the server when an entity rotates and moves
# https://wiki.vg/Protocol#Entity_Position_and_Rotation # https://wiki.vg/Protocol#Entity_Position_and_Rotation
@ -385,17 +361,3 @@ class DestroyEntitiesPacket(Packet):
for _ in range(self.count): for _ in range(self.count):
eid = VarInt.read(file_object) eid = VarInt.read(file_object)
self.entity_ids.append(eid) self.entity_ids.append(eid)
class EntityVelocityPacket(Packet):
# Sent to update entity's velocity
# https://wiki.vg/Protocol#Entity_Velocity
id = 0x46
packet_name = 'entity velocity'
definition = [
{'entity_id': VarInt},
{'velocity_x': Short},
{'velocity_y': Short},
{'velocity_z': Short},
]