Find chest openings within interaction range
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import unittest
|
||||
from munch import Munch
|
||||
|
||||
from minecraft.networking.types import BlockFace
|
||||
|
||||
from mosfet.info import blocks
|
||||
from mosfet.world import CHEST_OPENING_RADIUS, World
|
||||
|
||||
|
||||
class FakeChunks:
|
||||
def __init__(self, states):
|
||||
self.states = states
|
||||
|
||||
def get_block_at(self, x, y, z):
|
||||
return self.states.get((x, y, z), blocks.AIR)
|
||||
|
||||
|
||||
class CacheOpeningTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.chest = (0, 64, 0)
|
||||
chest_state = min(blocks.CHEST_IDS)
|
||||
stone = blocks.STONE
|
||||
states = {self.chest: chest_state}
|
||||
for x in range(-4, 5):
|
||||
for z in range(-4, 5):
|
||||
states[(x, 63, z)] = stone
|
||||
self.world = World(Munch(chunks=FakeChunks(states)))
|
||||
|
||||
def test_openings_include_visible_positions_up_to_configured_radius(self):
|
||||
opening = (3, 64, 0)
|
||||
openings = self.world.find_cache_openings(
|
||||
self.chest, center=(3, 64, 0))
|
||||
by_position = {tuple(candidate['position']): candidate
|
||||
for candidate in openings}
|
||||
|
||||
self.assertEqual(CHEST_OPENING_RADIUS, 3)
|
||||
self.assertIn(opening, by_position)
|
||||
self.assertTrue(all(candidate['hit_distance'] <= CHEST_OPENING_RADIUS
|
||||
for candidate in openings))
|
||||
self.assertIn(by_position[opening]['face'], (
|
||||
BlockFace.NORTH, BlockFace.SOUTH, BlockFace.WEST,
|
||||
BlockFace.EAST, BlockFace.TOP,
|
||||
))
|
||||
self.assertEqual(len(by_position[opening]['cursor']), 3)
|
||||
|
||||
def test_range_is_measured_from_eye_to_interaction_surface(self):
|
||||
opening = (3, 63, 0)
|
||||
self.world.g.chunks.states[opening] = blocks.AIR
|
||||
self.world.g.chunks.states[(3, 62, 0)] = blocks.STONE
|
||||
|
||||
openings = self.world.find_cache_openings(
|
||||
self.chest, center=opening)
|
||||
by_position = {tuple(candidate['position']): candidate
|
||||
for candidate in openings}
|
||||
|
||||
self.assertIn(opening, by_position)
|
||||
self.assertLessEqual(by_position[opening]['hit_distance'], 3)
|
||||
|
||||
def test_sign_collision_shape_does_not_block_sight_but_solid_block_does(self):
|
||||
start = (3.5, 65.62, 0.5)
|
||||
target = (0.5, 64.875, 0.5)
|
||||
sign_state = blocks.MCD_BLOCKS['oak_sign']['minStateId']
|
||||
obstruction = (1, 65, 0)
|
||||
self.world.g.chunks.states[obstruction] = sign_state
|
||||
|
||||
self.assertTrue(self.world._has_cache_line_of_sight(
|
||||
start, target, self.chest))
|
||||
|
||||
self.world.g.chunks.states[obstruction] = blocks.STONE
|
||||
self.assertFalse(self.world._has_cache_line_of_sight(
|
||||
start, target, self.chest))
|
||||
|
||||
def test_virtual_chest_openings_are_found_before_placement(self):
|
||||
target = (0, 65, 0)
|
||||
for x in range(-3, 4):
|
||||
for z in range(-3, 4):
|
||||
self.world.g.chunks.states[(x, 64, z)] = blocks.STONE
|
||||
|
||||
openings = self.world.find_cache_openings(
|
||||
target, center=(3, 65, 0))
|
||||
|
||||
self.assertTrue(openings)
|
||||
self.assertTrue(all(candidate['target'] == target
|
||||
for candidate in openings))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -93,8 +93,8 @@ class ChestDetectionTests(unittest.TestCase):
|
||||
chunks=Munch(get_block_at=lambda *_position: None),
|
||||
world=Munch(_double_chest_positions=lambda _position:
|
||||
(self.position,)))
|
||||
game.place_block = lambda location, face: sent.append(
|
||||
(location, face))
|
||||
game.place_block = lambda location, face, **kwargs: sent.append(
|
||||
(location, face, kwargs))
|
||||
|
||||
game.open_container(self.position)
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@ import unittest
|
||||
from munch import Munch
|
||||
|
||||
from minecraft.networking.modern import ClientTickEnd, UseItemOnBlockPacket
|
||||
from minecraft.networking.types import BlockFace
|
||||
from mosfet.game import Game
|
||||
from mosfet.info import blocks
|
||||
from mosfet.protocol.modern import PlayerInputPacket
|
||||
|
||||
|
||||
@@ -15,6 +17,28 @@ class FakeConnection:
|
||||
|
||||
|
||||
class SneakPlacementTests(unittest.TestCase):
|
||||
def test_open_container_sends_visible_face_and_hit_cursor(self):
|
||||
chest = (2, 65, -4)
|
||||
connection = FakeConnection()
|
||||
game = Game.__new__(Game)
|
||||
game.g = Munch(
|
||||
connection=connection,
|
||||
chunks=Munch(get_block_at=lambda *position:
|
||||
min(blocks.CHEST_IDS) if tuple(position) == chest
|
||||
else None),
|
||||
world=Munch())
|
||||
game.sequence = 0
|
||||
|
||||
game.open_container(
|
||||
chest, face=BlockFace.EAST, cursor=(0.9375, 0.5, 0.5))
|
||||
|
||||
packet = next(packet for packet, _force in connection.packets
|
||||
if isinstance(packet, UseItemOnBlockPacket))
|
||||
self.assertEqual(packet.location, chest)
|
||||
self.assertEqual(packet.face, BlockFace.EAST)
|
||||
self.assertEqual((packet.cursor_x, packet.cursor_y, packet.cursor_z),
|
||||
(0.9375, 0.5, 0.5))
|
||||
|
||||
def test_sneaking_wraps_block_placement_and_is_released(self):
|
||||
connection = FakeConnection()
|
||||
game = Game.__new__(Game)
|
||||
|
||||
Reference in New Issue
Block a user