Exemplo n.º 1
0
async def cast_entity(
        entity: Entity,
        position: PositionComponent,
        update=True,
        on_connect=False,
        reason=None
):
    assert isinstance(position, PositionComponent)
    from core.src.world.builder import events_subscriber_service, events_publisher_service
    loop = asyncio.get_event_loop()
    if update:
        current_position = await get_components_for_entity(entity, (PositionComponent, 'coord'))
        position.add_previous_position(current_position)
        entity = entity.set_for_update(position).set_room(Room(position))
        update_response = await update_entities(entity.set_for_update(position))
        if not update_response:
            LOGGER.core.error(
                'Impossible to cast entity {}'.format(entity.entity_id))
            return
    area = Area(position).make_coordinates()
    listeners = await get_eligible_listeners_for_area(area)
    entity.entity_id in listeners and listeners.remove(entity.entity_id)
    if on_connect:
        await events_publisher_service.on_entity_appear_position(entity, position, reason, targets=listeners)
        loop.create_task(events_subscriber_service.subscribe_events(entity))
    else:
        pass
        await events_publisher_service.on_entity_change_position(entity, position, reason, targets=listeners)
    entity.set_component(position)
    return True
 async def asyncio_test(self):
     sut = RedisMapRepository(get_redis_factory(RedisType.DATA))
     await (await sut.redis()).flushdb()
     max_x, max_y, max_z = 500, 500, 1
     sut.max_y = max_y
     sut.max_x = max_x
     start = time.time()
     i = 0
     print('\nBaking {}x{} map'.format(max_x, max_y))
     for x in range(max_x, -1, -1):
         roomz = OrderedDict()
         for y in range(max_y, -1, -1):
             for z in range(0, max_z):
                 i += 1
                 position = PositionComponent(
                     coord='{},{},{}'.format(x, y, z))
                 roomz['{}.{}.{}'.format(x, y, z)] = Room(
                     position=position,
                     terrain=random.choice(
                         [TerrainEnum.WALL_OF_BRICKS, TerrainEnum.PATH]),
                 )
         print(i, ' rooms saved')
         await sut.set_rooms(*roomz.values())
     print('\n{}x{} map baked in {}'.format(max_x, max_y,
                                            time.time() - start))
     start = time.time()
     print('\nFetching {}x{} map'.format(max_x, max_y))
     tot = 0
     for x in range(0, max_x):
         res = await sut.get_rooms(*(PositionComponent(
             coord='{},{},{}'.format(x, y, 0)) for y in range(0, max_y)))
         tot += len(res)
     print('\n{}x{} map fetched in {} - total: {}'.format(
         max_x, max_y,
         time.time() - start, tot))
Exemplo n.º 3
0
 async def get_rooms_on_y(self,
                          y: int,
                          from_x: int,
                          to_x: int,
                          z: int,
                          get_content=True):
     assert to_x > from_x
     redis = await self.redis()
     pipeline = redis.pipeline()
     if z:
         packed_coordinates = (self._pack_coords(x, y, z)
                               for x in range(from_x, to_x))
         pipeline.hmget(self.z_valued_rooms_data_key, *packed_coordinates)
     else:
         k = self._coords_to_int(from_x, y)
         pipeline.getrange(self.terrains_bitmap_key, k,
                           k + ((to_x - from_x) - 1))
     get_content and [
         self._get_room_content(pipeline, x, y, z)
         for x in range(from_x, to_x)
     ]
     response = []
     i = 0
     result = await pipeline.execute()
     if z:
         res = result[0]
         d = 0
         for key, value in res[0].items():
             terrain = int(value)
             response.append(
                 Room(
                     position=PositionComponent().set_list_coordinates(
                         [from_x + d, y, z]),
                     terrain=TerrainEnum(terrain),
                 ))
             d += 1
         for res in result[i + 1]:
             response[i].add_entity_ids(list(res))
     else:
         terrains = struct.unpack('B' * (to_x - from_x), result[0])
         for d in range(0, to_x - from_x):
             response.append(
                 Room(position=PositionComponent().set_list_coordinates(
                     [from_x + d, y, z]),
                      terrain=TerrainEnum(terrains[d]),
                      entity_ids=get_content
                      and [int(x) for x in result[d + 1]] or []))
     return response
Exemplo n.º 4
0
def apply_delta_to_position(room_position: PositionComponent, delta: typing.Tuple[int, int, int]):
    return PositionComponent().set_list_coordinates(
        [
            room_position.x + delta[0],
            room_position.y + delta[1],
            room_position.z + delta[2]
        ]
    )
Exemplo n.º 5
0
async def search_entities_in_container_by_keyword(container: InventoryComponent, keyword: str) -> typing.List:
    """
    Search for entities in the provided container, using the keyword param.
    Accept a wildcard as the final character of the keyword argument, to search for multiple entities.
    """
    await populate_container(container, AttributesComponent)
    if '*' not in keyword:
        for c_entity in container.populated:
            if c_entity.get_component(AttributesComponent).keyword.startswith(keyword):
                c_entity.set_component(PositionComponent().parent_of.set(container.owned_by().entity_id))
                return [c_entity]
        return []
    else:
        res = []
        assert keyword[-1] == '*'
        keyword = keyword.replace('*', '')
        for c_entity in container.populated:
            if c_entity.get_component(AttributesComponent).keyword.startswith(keyword):
                c_entity.set_component(PositionComponent().parent_of.set(container.owned_by().entity_id))
                res.append(c_entity)
        return res
Exemplo n.º 6
0
def move_entity_from_container(
        entity: Entity,
        target: (PositionComponent, InventoryComponent),
        current_owner: Entity = None
):
    current_position = entity.get_component(PositionComponent)
    if current_position.parent_of:
        assert current_owner and current_owner.entity_id == current_position.parent_of, (
                current_owner and current_owner.entity_id, current_position.parent_of
        )
        current_owner.get_component(InventoryComponent).content.remove(entity.entity_id)
        current_owner.set_for_update(current_owner.get_component(InventoryComponent))

    if isinstance(target, InventoryComponent):
        target_owner = target.owned_by()
        new_position = PositionComponent().parent_of.set(target_owner.entity_id).coord.null()
        new_position.add_previous_position(current_position)
        target.content.append(entity.entity_id)
        target_owner.set_for_update(target)
        entity.set_for_update(new_position)

    elif isinstance(target, PositionComponent):
        assert target.coord.value
        new_position = PositionComponent().parent_of.null().coord.set(target.coord.value)
        entity.set_for_update(new_position)

    else:
        raise ValueError('Target must be type PosComponent or ContainerComponent, is: %s' % target)
    return entity
Exemplo n.º 7
0
 async def on_event(self, entity_id: int, message: typing.Dict,
                    room: typing.Tuple, transport_id: str):
     room = PositionComponent(coord='{},{},{}'.format(*room))
     entity = Entity(entity_id).set_component(
         SystemComponent().connection.set(transport_id))
     await load_components(entity, PositionComponent)
     curr_pos = entity.get_component(PositionComponent)
     interest_type = await self._get_message_interest_type(
         entity, room, curr_pos)
     if not interest_type.value:
         return
     await self.publish_event(entity, message, room, interest_type,
                              curr_pos)
Exemplo n.º 8
0
def parse_lines(lines):
    lines = [l.strip() for l in lines]
    max_y = len(lines) - 1
    max_x = max([len(line) for line in lines]) - 1
    rooms = []
    for y in range(max_y, -1, -1):
        for x in range(0, max_x + 1):
            room_enum = terrains[lines[y][x]]
            if room_enum:
                rooms.append(
                    Room(position=PositionComponent().set_list_coordinates(
                        [x, max_y - y, 0]),
                         terrain=room_enum))
    return rooms
Exemplo n.º 9
0
 async def _do_follow(self, follower_id: int, event: typing.Dict):
     current_followed_id = self._follow_by_follower.get(follower_id)
     if current_followed_id != event['entity']['id']:
         LOGGER.core.error('Error on follow system')
         return
     entity = await load_components(Entity(follower_id), SystemComponent, PositionComponent)
     if entity.get_component(PositionComponent).list_coordinates != event['from']:
         LOGGER.core.error('Error on follow system')
         return
     await do_move_entity(
         entity,
         Room(PositionComponent().set_list_coordinates(event['to'])),
         None,
         reason="movement",
         emit_message=False
     )
    async def asyncio_test(self):
        sut = RedisMapRepository(get_redis_factory(RedisType.DATA))
        await (await sut.redis()).flushdb()
        max_x, max_y = 50, 50
        sut.max_y = max_y
        sut.max_x = max_x
        start = time.time()
        print('\nBaking {}x{} map'.format(max_x, max_y))
        roomz = OrderedDict()
        for x in range(0, max_x):
            for y in range(0, max_y):
                position = PositionComponent(coord='{},{},{}'.format(x, y, 0))
                roomz['{}.{}.{}'.format(x, y, 0)] = Room(
                    position=position,
                    terrain=random.choice(
                        [TerrainEnum.WALL_OF_BRICKS, TerrainEnum.PATH]))
        await sut.set_rooms(*roomz.values())
        print('\n{}x{} map baked in {}'.format(max_x, max_y,
                                               time.time() - start))

        from_x, to_x = 0, 9
        for yy in range(0, 210, 10):
            futures = [
                sut.get_rooms_on_y(0, from_x, to_x, 0) for _ in range(0, yy)
            ]
            s = time.time()
            res = await asyncio.gather(*futures)
            print('Get line of {} rooms. Concurrency: '.format(to_x - from_x),
                  yy, ' users. Time: {:.8f}'.format(time.time() - s))
            for r in res:
                for req in range(0, to_x):
                    k = '{}.{}.{}'.format(from_x + req, 0, 0)
                    self.assertEqual([
                        r[req].position.x, r[req].position.y, r[req].position.z
                    ], [
                        roomz[k].position.x, roomz[k].position.y,
                        roomz[k].position.z
                    ])
    async def async_test(self):
        sut = RedisMapRepository(get_redis_factory(RedisType.DATA))
        await (await sut.redis()).flushdb()
        futures = []
        d = {}
        i = 0
        max_x, max_y, max_z = 25, 25, 5
        sut.max_y = max_y
        sut.max_x = max_x
        start = time.time()
        for x in range(0, max_x):
            for y in range(0, max_y):
                for z in range(0, max_z):
                    i += 1
                    d['{}.{}.{}'.format(x, y, z)] = [
                        random.randint(0, 65530),
                        random.randint(0, 65530)
                    ]
                    futures.append(
                        sut.set_room(
                            Room(position=PositionComponent(
                                coord='{},{},{}'.format(x, y, z)),
                                 terrain=TerrainEnum.WALL_OF_BRICKS)))
        await asyncio.gather(*futures)
        for x in range(0, max_x):
            for y in range(0, max_y):
                for z in range(0, max_z):
                    room = await sut.get_room(
                        PositionComponent(coord='{},{},{}'.format(x, y, z)))
                    self.assertEqual(
                        [room.position.x, room.position.y, room.position.z],
                        [x, y, z])
        print(
            '\n', i,
            ' rooms tested NO pipeline in {:.10f}'.format(time.time() - start))

        await (await sut.redis()).flushdb()
        _start = time.time()
        roomz = OrderedDict()
        positions = []
        for x in range(0, max_x):
            for y in range(0, max_y):
                for z in range(0, max_z):
                    position = PositionComponent(
                        coord='{},{},{}'.format(x, y, z))
                    positions.append(position)
                    roomz['{}.{}.{}'.format(x, y, z)] = Room(
                        position=position,
                        terrain=TerrainEnum.WALL_OF_BRICKS,
                    )
        await sut.set_rooms(*roomz.values())
        rooms = await sut.get_rooms(*positions)
        for i, room in enumerate(rooms):
            self.assertEqual([
                room.position.x,
                room.position.y,
                room.position.z,
            ], [
                positions[i].x,
                positions[i].y,
                positions[i].z,
            ])
        print(
            '\n', i + 1,
            ' rooms tested WITH pipeline in {:.10f}'.format(time.time() -
                                                            _start))

        positions = []
        i = 0
        for x in range(0, 9):
            for y in range(0, 9):
                positions.append(
                    PositionComponent(coord='{},{},{}'.format(x, y, 0)))
                i += 1
        print('\n Starting benchmarks: \n')
        for x in range(1, 110, 10):
            futures = [sut.get_rooms(*positions) for _ in range(0, x)]
            s = time.time()
            await asyncio.gather(*futures)
            print('Rooms: ', i, '. Concurrency: ', x,
                  ' users. Time: {:.8f}'.format(time.time() - s))

        positions = []
        i = 0
        for x in range(0, 9):
            y = 1
            positions.append(
                PositionComponent(coord='{},{},{}'.format(x, y, 0)))
            i += 1

        for x in range(1, 110, 10):
            futures = [sut.get_rooms(*positions) for _ in range(0, x)]
            s = time.time()
            await asyncio.gather(*futures)
            print('Rooms: ', i, '. Concurrency: ', x,
                  ' users. Time: {:.8f}'.format(time.time() - s))
Exemplo n.º 12
0
def get_base_room_for_entity(entity: Entity):
    return PositionComponent().set_list_coordinates([19, 1, 0])  # TODO FIXME
Exemplo n.º 13
0
 def test_relative_position(self):
     pos = PositionComponent(coord='2,3,0')
     pos2 = PositionComponent(coord='1,4,0')
     area = Area(pos, square_size=11)
     self.assertEqual(area.get_relative_position(pos2), 48)
     print('test area done')