Beispiel #1
0
 def move_collisions(self, b_obj, vx, vy, vz):
     zero_vels = False
     if self.is_in_web(b_obj):
         vx *= 0.25
         vy *= 0.05000000074505806
         vz *= 0.25
         b_obj.velocities[0] = 0
         b_obj.velocities[1] = 0
         b_obj.velocities[2] = 0
     aabbs = self.world.grid.aabbs_in(b_obj.aabb.extend_to(vx, vy, vz))
     b_bb = b_obj.aabb
     dy = vy
     for bb in aabbs:
         dy = b_bb.calculate_axis_offset(bb, dy, 1)
     b_bb = b_bb.offset(dy=dy)
     dx = vx
     for bb in aabbs:
         dx = b_bb.calculate_axis_offset(bb, dx, 0)
     b_bb = b_bb.offset(dx=dx)
     dz = vz
     for bb in aabbs:
         dz = b_bb.calculate_axis_offset(bb, dz, 2)
     b_bb = b_bb.offset(dz=dz)
     if vy != dy and vy < 0 and (dx != vx or dz != vz):
         st = config.MAX_STEP_HEIGHT
         aabbs = self.world.grid.aabbs_in(b_obj.aabb.extend_to(vx, st, vz))
         b_bbs = b_obj.aabb
         dys = st
         for bb in aabbs:
             dys = b_bbs.calculate_axis_offset(bb, dys, 1)
         b_bbs = b_bbs.offset(dy=dys)
         dxs = vx
         for bb in aabbs:
             dxs = b_bbs.calculate_axis_offset(bb, dxs, 0)
         b_bbs = b_bbs.offset(dx=dxs)
         dzs = vz
         for bb in aabbs:
             dzs = b_bbs.calculate_axis_offset(bb, dzs, 2)
         b_bbs = b_bbs.offset(dz=dzs)
         if fops.gt(dxs * dxs + dzs * dzs, dx * dx + dz * dz):
             dx = dxs
             dy = dys
             dz = dzs
             b_bb = b_bbs
     b_obj.on_ground = vy != dy and vy < 0
     b_obj.is_collided_horizontally = dx != vx or dz != vz
     b_obj.horizontally_blocked = not fops.eq(dx, vx) and not fops.eq(dz, vz)
     if not fops.eq(vx, dx):
         b_obj.velocities[0] = 0
     if not fops.eq(vy, dy):
         b_obj.velocities[1] = 0
     if not fops.eq(vz, dz):
         b_obj.velocities[2] = 0
     b_obj.x = b_bb.posx
     b_obj.y = b_bb.min_y
     b_obj.z = b_bb.posz
     self.do_block_collision(b_obj)
Beispiel #2
0
 def standing_on_solidblock(self, bb):
     standing_on = None
     for col_bb in self.collision_aabbs_in(bb):
         if fops.eq(col_bb.max_y, bb.min_y):
             standing_on = self.get_block(col_bb.grid_x, col_bb.grid_y, col_bb.grid_z)
             if standing_on.x == bb.gridpos_x and standing_on.z == bb.gridpos_z:
                 break
     if standing_on is not None:
         if not fops.eq(bb.grid_y, standing_on.y):
             standing_on = self.get_block(standing_on.x, standing_on.y + 1, standing_on.z)
     return standing_on
Beispiel #3
0
 def standing_on_solidblock(self, bb):
     standing_on = None
     for col_bb in self.collision_aabbs_in(bb):
         if fops.eq(col_bb.max_y, bb.min_y):
             standing_on = self.get_block(col_bb.grid_x, col_bb.grid_y,
                                          col_bb.grid_z)
             if standing_on.x == bb.gridpos_x and standing_on.z == bb.gridpos_z:
                 break
     if standing_on is not None:
         if not fops.eq(bb.grid_y, standing_on.y):
             standing_on = self.get_block(standing_on.x, standing_on.y + 1,
                                          standing_on.z)
     return standing_on
Beispiel #4
0
 def move_collisions(self, b_obj, vx, vy, vz):
     if self.is_in_web(b_obj):
         vx *= 0.25
         vy *= 0.05000000074505806
         vz *= 0.25
         b_obj.velocities.x = 0
         b_obj.velocities.y = 0
         b_obj.velocities.z = 0
     aabbs = self.world.grid.collision_aabbs_in(
         b_obj.aabb.extend_to(vx, vy, vz))
     b_bb = b_obj.aabb
     dy = vy
     if not fops.eq(vy, 0):
         for bb in aabbs:
             dy = b_bb.calculate_axis_offset(bb, dy, 1)
         b_bb = b_bb.offset(dy=dy)
     dx = vx
     if not fops.eq(vx, 0):
         for bb in aabbs:
             dx = b_bb.calculate_axis_offset(bb, dx, 0)
         b_bb = b_bb.offset(dx=dx)
     dz = vz
     if not fops.eq(vz, 0):
         for bb in aabbs:
             dz = b_bb.calculate_axis_offset(bb, dz, 2)
         b_bb = b_bb.offset(dz=dz)
     if vy != dy and vy < 0 and (dx != vx or dz != vz):
         st = config.MAX_STEP_HEIGHT
         aabbs = self.world.grid.collision_aabbs_in(
             b_obj.aabb.extend_to(vx, st, vz))
         b_bbs = b_obj.aabb
         dys = st
         for bb in aabbs:
             dys = b_bbs.calculate_axis_offset(bb, dys, 1)
         b_bbs = b_bbs.offset(dy=dys)
         dxs = vx
         for bb in aabbs:
             dxs = b_bbs.calculate_axis_offset(bb, dxs, 0)
         b_bbs = b_bbs.offset(dx=dxs)
         dzs = vz
         for bb in aabbs:
             dzs = b_bbs.calculate_axis_offset(bb, dzs, 2)
         b_bbs = b_bbs.offset(dz=dzs)
         if fops.gt(dxs * dxs + dzs * dzs, dx * dx + dz * dz):
             dx = dxs
             dy = dys
             dz = dzs
             b_bb = b_bbs
     b_obj.on_ground = vy != dy and vy < 0
     b_obj.is_collided_horizontally = dx != vx or dz != vz
     b_obj.horizontally_blocked = not fops.eq(dx, vx) and not fops.eq(
         dz, vz)
     if not fops.eq(vx, dx):
         b_obj.velocities.x = 0
     if not fops.eq(vy, dy):
         b_obj.velocities.y = 0
     if not fops.eq(vz, dz):
         b_obj.velocities.z = 0
     b_obj.set_xyz(b_bb.posx, b_bb.min_y, b_bb.posz)
     self.do_block_collision(b_obj)
Beispiel #5
0
 def is_standing(self, b_obj):
     col_d, _ = self.world.grid.min_collision_between(
         b_obj.aabb, b_obj.aabb - (0, 1, 0))
     if col_d is None:
         stand = False
     else:
         stand = fops.eq(col_d, 0)
     return stand
Beispiel #6
0
 def collision_distance(self, collidee, axis=None, direction=None):
     for i in xrange(3):
         if i == axis:
             continue
         if fops.lte(self.maxs[i], collidee.mins[i]) or \
                 fops.gte(self.mins[i], collidee.maxs[i]):
             return None
     p = None
     if direction < 0:
         if fops.eq(self.mins[axis], collidee.maxs[axis]):
             p = 0
         elif fops.gt(self.mins[axis], collidee.maxs[axis]):
             p = self.mins[axis] - collidee.maxs[axis]
     else:
         if fops.eq(collidee.mins[axis], self.maxs[axis]):
             p = 0
         elif fops.gt(collidee.mins[axis], self.maxs[axis]):
             p = collidee.mins[axis] - self.maxs[axis]
     return p
Beispiel #7
0
 def collision_distance(self, collidee, axis=None, direction=None):
     for i in xrange(3):
         if i == axis:
             continue
         if fops.lte(self.maxs[i], collidee.mins[i]) or \
                 fops.gte(self.mins[i], collidee.maxs[i]):
             return None
     p = None
     if direction < 0:
         if fops.eq(self.mins[axis], collidee.maxs[axis]):
             p = 0
         elif fops.gt(self.mins[axis], collidee.maxs[axis]):
             p = self.mins[axis] - collidee.maxs[axis]
     else:
         if fops.eq(collidee.mins[axis], self.maxs[axis]):
             p = 0
         elif fops.gt(collidee.mins[axis], self.maxs[axis]):
             p = collidee.mins[axis] - self.maxs[axis]
     return p
Beispiel #8
0
 def standing_on_solidblock(self, bb):
     standing_on = None
     blocks = self.blocks_in_aabb(bb.extend_to(dy=-1))
     dvect = (0, -1, 0)
     for blk in blocks:
         col, rel_d, _ = blk.sweep_collision(bb, dvect)
         if col and fops.eq(rel_d, 0):
             standing_on = blk
             if standing_on.x == bb.grid_x and standing_on.z == bb.grid_z:
                 break
     return standing_on
Beispiel #9
0
    def sweep_collision(self, collidee, v, debug=False):
        """
        self moving by v, collidee stationery
        based on http://bit.ly/3grWzs
        """
        u_0 = [2, 2, 2]
        u_1 = [1, 1, 1]
        dists = [None, None, None]
        for i in xrange(3):
            if fops.lte(self.maxs[i], collidee.mins[i]) and fops.gt(v[i], 0):
                d = collidee.mins[i] - self.maxs[i]
                dists[i] = d
                u_0[i] = d / v[i]
            elif fops.lte(collidee.maxs[i], self.mins[i]) and fops.lt(v[i], 0):
                d = collidee.maxs[i] - self.mins[i]
                dists[i] = d
                u_0[i] = d / v[i]
            elif fops.eq(v[i], 0) and \
                    not(fops.lte(self.maxs[i], collidee.mins[i]) or
                        fops.gte(self.mins[i], collidee.maxs[i])):
                u_0[i] = 0
            elif not(fops.lte(self.maxs[i], collidee.mins[i]) or
                     fops.gte(self.mins[i], collidee.maxs[i])):
                u_0[i] = 0
            if fops.gte(collidee.maxs[i], self.mins[i]) and fops.gt(v[i], 0):
                d = collidee.maxs[i] - self.mins[i]
                u_1[i] = d / v[i]
            elif fops.gte(self.maxs[i], collidee.mins[i]) and fops.lt(v[i], 0):
                d = collidee.mins[i] - self.maxs[i]
                u_1[i] = d / v[i]

        if max(u_0) == 2:
            u0 = None
            col = False
        else:
            u0 = max(u_0)
            u1 = min(u_1)
            if fops.gte(u0, 1.0):
                col = False
            else:
                col = fops.lte(u0, u1)
        return col, u0
Beispiel #10
0
 def sweep_collision(self, bb, vect, debug=False, max_height=False):
     boxes = self.grid_bounding_box
     if len(boxes) == 0:
         raise Exception(
             "0 bounding boxes from block %s, cannot handle that" % self)
     elif len(boxes) == 1:
         col, rel_d = bb.sweep_collision(boxes[0], vect, debug=debug)
         return col, rel_d, boxes[0]
     else:
         col_rel_d = 1.1
         col_bb = None
         for box in boxes:
             col, rel_d = bb.sweep_collision(box, vect, debug=debug)
             if max_height and col and fops.eq(col_rel_d, rel_d):
                 if fops.lt(col_bb.max_y, bb.max_y):
                     col_bb = bb
             if col and fops.lt(rel_d, col_rel_d):
                 col_rel_d = rel_d
                 col_bb = bb
         return col_bb is not None, col_rel_d, col_bb
Beispiel #11
0
 def min_collision_between(self, bb1, bb2, horizontal=False, max_height=False):
     ubb = bb1.extend_to(dy=-1).union(bb2.extend_to(dy=-1))
     blcks = self.blocks_in_aabb(ubb)
     dvect = bb1.vector_to(bb2)
     if horizontal:
         dvect = (dvect[0], 0, dvect[2])
     col_rel_d = 1.1
     col_bb = None
     for blk in blcks:
         col, rel_d, bb = blk.sweep_collision(
             bb1, dvect, max_height=max_height)
         if col and fops.eq(col_rel_d, rel_d):
             if max_height:
                 if fops.lt(col_bb.max_y, bb.max_y):
                     col_bb = bb
         if col and fops.lt(rel_d, col_rel_d):
             col_rel_d = rel_d
             col_bb = bb
     if col_bb is not None:
         return col_rel_d * tools.vector_size(dvect), col_bb
     else:
         return None, None
Beispiel #12
0
 def check_status(self, b_obj):
     bb_stand = self.target_space.bb_stand
     elev = bb_stand.min_y - b_obj.aabb.min_y
     gs = GridSpace(self.world.grid, bb=b_obj.aabb)
     if not self.target_space._can_stand_on():
         self.world.grid.navgrid.delete_node(self.target_space.coords)
         log.msg('CANNOT STAND ON %s' % self.target_space)
         return Status.failure
     if b_obj.horizontally_blocked and not gs.can_go_between(self.target_space, debug=True):
         log.msg('CANNOT GO BETWEEN %s AND %s' % (b_obj.aabb, self.target_space))
         return Status.failure
     if self.bot.is_on_ladder(b_obj) or self.bot.is_in_water(b_obj):
         if b_obj.position_grid == self.target_space.coords:
             return Status.success
     if b_obj.aabb.horizontal_distance(bb_stand) < self.bot.current_motion(b_obj):
         self.was_at_target = True
         if fops.eq(elev, 0):
             return Status.success
     if b_obj.horizontally_blocked and b_obj.on_ground:
         if not gs.can_go(self.target_space):
             log.msg("I am stuck, let's try again? vels %s" %
                     str(b_obj.velocities))
             return Status.failure
     return Status.running
Beispiel #13
0
    def raycast_to_block(self, position, direction, max_distance=40):
        g_position = position.grid_shift()
        gx = g_position.x
        gy = g_position.y
        gz = g_position.z
        if fops.eq(0, direction.x):
            stepx = 0
            tdx = sys.float_info.max
        else:
            stepx = int(math.copysign(1, direction.x))
            tdx = abs(1 / direction.x)

        if fops.eq(0, direction.y):
            stepy = 0
            tdy = sys.float_info.max
        else:
            stepy = int(math.copysign(1, direction.y))
            tdy = abs(1 / direction.y)

        if fops.eq(0, direction.z):
            stepz = 0
            tdz = sys.float_info.max
        else:
            stepz = int(math.copysign(1, direction.z))
            tdz = abs(1 / direction.z)

        if stepx == 0:
            tmaxx = tdx
        elif stepx > 0:
            tmaxx = (math.floor(position.x) + 1 - position.x) * tdx
        else:
            tmaxx = (position.x - math.floor(position.x)) * tdx

        if stepy == 0:
            tmaxy = tdy
        elif stepy > 0:
            tmaxy = (math.floor(position.y) + 1 - position.y) * tdy
        else:
            tmaxy = (position.y - math.floor(position.y)) * tdy

        if stepz == 0:
            tmaxz = tdz
        elif stepz > 0:
            tmaxz = (math.floor(position.z) + 1 - position.z) * tdz
        else:
            tmaxz = (position.z - math.floor(position.z)) * tdz

        sqr_max_distance = max_distance * max_distance
        while True:
            if tmaxx < tmaxy:
                if tmaxx < tmaxz:
                    gx = gx + stepx
                    tmaxx = tmaxx + tdx
                else:
                    gz = gz + stepz
                    tmaxz = tmaxz + tdz

            else:
                if tmaxy < tmaxz:
                    gy = gy + stepy
                    tmaxy = tmaxy + tdy
                else:
                    gz = gz + stepz
                    tmaxz = tmaxz + tdz
            blk = self.get_block(gx, gy, gz)
            if blk.number != blocks.Air.number:
                return blk
            if (g_position.x - gx) ** 2 + (g_position.y - gy) ** 2 + (g_position.z - gz) ** 2 > sqr_max_distance:
                return blocks.Air(self, 0, 0, 0, 0)
Beispiel #14
0
 def has_point(self, p):
     return fops.eq(abs(self.a), abs(self.a1 - p[0])) and \
         fops.eq(abs(self.b), abs(self.b1 - p[1]))
Beispiel #15
0
 def touch_platform(self, center):
     if self.can_stand:
         return fops.eq(center.y, self.y)
     elif self.can_hold:
         return self.y < center.y and center.y < (self.y + 1)
Beispiel #16
0
 def touch_platform(self, center):
     if self.can_stand:
         return fops.eq(center.y, self.y)
     elif self.can_hold:
         return self.y < center.y and center.y < (self.y + 1)
Beispiel #17
0
    def raycast_to_block(self, position, direction, max_distance=40):
        g_position = position.grid_shift()
        gx = g_position.x
        gy = g_position.y
        gz = g_position.z
        if fops.eq(0, direction.x):
            stepx = 0
            tdx = sys.float_info.max
        else:
            stepx = int(math.copysign(1, direction.x))
            tdx = abs(1 / direction.x)

        if fops.eq(0, direction.y):
            stepy = 0
            tdy = sys.float_info.max
        else:
            stepy = int(math.copysign(1, direction.y))
            tdy = abs(1 / direction.y)

        if fops.eq(0, direction.z):
            stepz = 0
            tdz = sys.float_info.max
        else:
            stepz = int(math.copysign(1, direction.z))
            tdz = abs(1 / direction.z)

        if stepx == 0:
            tmaxx = tdx
        elif stepx > 0:
            tmaxx = (math.floor(position.x) + 1 - position.x) * tdx
        else:
            tmaxx = (position.x - math.floor(position.x)) * tdx

        if stepy == 0:
            tmaxy = tdy
        elif stepy > 0:
            tmaxy = (math.floor(position.y) + 1 - position.y) * tdy
        else:
            tmaxy = (position.y - math.floor(position.y)) * tdy

        if stepz == 0:
            tmaxz = tdz
        elif stepz > 0:
            tmaxz = (math.floor(position.z) + 1 - position.z) * tdz
        else:
            tmaxz = (position.z - math.floor(position.z)) * tdz

        sqr_max_distance = max_distance * max_distance
        while True:
            if tmaxx < tmaxy:
                if tmaxx < tmaxz:
                    gx = gx + stepx
                    tmaxx = tmaxx + tdx
                else:
                    gz = gz + stepz
                    tmaxz = tmaxz + tdz

            else:
                if tmaxy < tmaxz:
                    gy = gy + stepy
                    tmaxy = tmaxy + tdy
                else:
                    gz = gz + stepz
                    tmaxz = tmaxz + tdz
            blk = self.get_block(gx, gy, gz)
            if blk.number != blocks.Air.number:
                return blk
            if (g_position.x - gx)**2 + (g_position.y - gy)**2 + (
                    g_position.z - gz)**2 > sqr_max_distance:
                return blocks.Air(self, 0, 0, 0, 0)
Beispiel #18
0
 def horizontal_direction_to(self, bb):
     x, _, z = self.vector_to(bb)
     size = math.hypot(x, z)
     if fops.eq(size, 0):
         return (0, 0)
     return (x / size, z / size)
Beispiel #19
0
 def move(self, b_obj):
     self.clip_abs_velocities(b_obj)
     is_in_water = self.handle_water_movement(b_obj)
     is_in_lava = self.handle_lava_movement(b_obj)
     if b_obj.is_jumping:
         if is_in_water or is_in_lava:
             b_obj.velocities[1] += config.SPEED_LIQUID_JUMP
         elif b_obj.on_ground:
             b_obj.velocities[1] = config.SPEED_JUMP
         elif self.is_on_ladder(b_obj):
             b_obj.velocities[1] = config.SPEED_CLIMB
         b_obj.is_jumping = False
     if is_in_water:
         if b_obj.floating_flag:
             if self.head_inside_water(b_obj):
                 b_obj.velocities[1] += config.SPEED_LIQUID_JUMP
             else:
                 x, y, z = b_obj.aabb.grid_bottom_center
                 b_up = self.world.grid.get_block(x, y + 1, z)
                 b_down = self.world.grid.get_block(x, y - 1, z)
                 b_cent = self.world.grid.get_block(x, y, z)
                 no_up = not b_up.is_water and b_down.collidable and fops.eq(b_down.max_y, y)
                 if (not no_up and b_cent.is_water and fops.gt(b_cent.y + 0.5, b_obj.aabb.min_y)) or isinstance(b_up, blocks.StillWater):
                     b_obj.velocities[1] += config.SPEED_LIQUID_JUMP
         orig_y = b_obj.y
         self.update_directional_speed(b_obj, 0.02, balance=True)
         self.move_collisions(b_obj, b_obj.velocities[0], b_obj.velocities[1], b_obj.velocities[2])
         b_obj.velocities[0] *= 0.800000011920929
         b_obj.velocities[1] *= 0.800000011920929
         b_obj.velocities[2] *= 0.800000011920929
         b_obj.velocities[1] -= 0.02
         if b_obj.is_collided_horizontally and \
                 self.is_offset_in_liquid(b_obj, b_obj.velocities[0],
                                          b_obj.velocities[1] + 0.6 -
                                          b_obj.y + orig_y,
                                          b_obj.velocities[2]):
             b_obj.velocities[1] = 0.30000001192092896
     elif is_in_lava:
         orig_y = self.y
         self.update_directional_speed(b_obj, 0.02)
         self.move_collisions(b_obj, b_obj.velocities[0], b_obj.velocities[1], b_obj.velocities[2])
         b_obj.velocities[0] *= 0.5
         b_obj.velocities[1] *= 0.5
         b_obj.velocities[2] *= 0.5
         b_obj.velocities[1] -= 0.02
         if b_obj.is_collided_horizontally and \
                 self.is_offset_in_liquid(b_obj, self.velocities[0],
                                          self.velocities[1] + 0.6 -
                                          self.y + orig_y,
                                          self.velocities[2]):
             self.velocities[1] = 0.30000001192092896
     else:
         slowdown = self.current_slowdown(b_obj)
         self.update_directional_speed(b_obj, self.current_speed_factor(b_obj))
         self.clip_ladder_velocities(b_obj)
         self.move_collisions(b_obj, b_obj.velocities[0], b_obj.velocities[1], b_obj.velocities[2])
         if b_obj.is_collided_horizontally and self.is_on_ladder(b_obj):
             b_obj.velocities[1] = 0.2
         b_obj.velocities[1] -= config.BLOCK_FALL
         b_obj.velocities[1] *= config.DRAG
         b_obj.velocities[0] *= slowdown
         b_obj.velocities[2] *= slowdown