Ejemplo n.º 1
0
 def sweep_collision(self, collidee, v, debug=False):
     """
     self (collider) moving by v, collidee stationery
     based on http://bit.ly/3grWzs
     """
     u_0 = [2, 2, 2]
     u_1 = [1, 1, 1]
     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]
             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]
             u_0[i] = d / v[i]
         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]
     u0 = max(u_0)
     if u0 == 2 or fops.gte(u0, 1.0):
         col = False
     else:
         col = fops.lte(u0, min(u_1))
     return col, u0
Ejemplo n.º 2
0
 def action(self):
     b_obj = self.blackboard.bot_object
     self.status = self._check_status(b_obj)
     if self.status != Status.running:
         return
     on_ladder = self.blackboard.bot_is_on_ladder(b_obj)
     in_water = self.blackboard.bot_is_in_water(b_obj)
     if on_ladder or in_water:
         elev = self.target_state.platform_y - b_obj.y
         if fops.gt(elev, 0):
             self.jump(b_obj)
             self.move(b_obj)
         elif fops.lt(elev, 0):
             self.move(b_obj)
         else:
             if on_ladder:
                 self.sneak(b_obj)
             self.move(b_obj)
     elif self.blackboard.bot_is_standing(b_obj):
         elev = self.target_state.platform_y - b_obj.y
         if fops.lte(elev, 0):
             self.move(b_obj)
         elif fops.gt(elev, 0):
             if self.start_state.base_in(b_obj.aabb):
                 self.jump(b_obj)
             self.move(b_obj)
     else:
         self.move(b_obj)
Ejemplo n.º 3
0
 def _tick(self):
     if self.cancelled:
         self.status = Status.failure
         return
     b_obj = self.bot.bot_object
     self.status = self.check_status(b_obj)
     if self.status != Status.running:
         return
     on_ladder = self.bot.is_on_ladder(b_obj)
     in_water = self.bot.is_in_water(b_obj)
     if on_ladder or in_water:
         elev = self.target_state.platform_y - b_obj.y
         if fops.gt(elev, 0):
             self.jump(b_obj)
             self.move(b_obj)
         elif fops.lt(elev, 0):
             self.move(b_obj)
         else:
             if on_ladder:
                 self.sneak(b_obj)
             self.move(b_obj)
     elif self.bot.is_standing(b_obj):
         elev = self.target_state.platform_y - b_obj.y
         if fops.lte(elev, 0):
             self.move(b_obj)
         elif fops.gt(elev, 0):
             if self.start_state.base_in(b_obj.aabb):
                 self.jump(b_obj)
             self.move(b_obj)
     else:
         self.move(b_obj)
Ejemplo n.º 4
0
 def sweep_collision(self, collidee, v, debug=False):
     """
     self (collider) moving by v, collidee stationery
     based on http://bit.ly/3grWzs
     """
     u_0 = [2, 2, 2]
     u_1 = [1, 1, 1]
     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]
             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]
             u_0[i] = d / v[i]
         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]
     u0 = max(u_0)
     if u0 == 2 or fops.gte(u0, 1.0):
         col = False
     else:
         col = fops.lte(u0, min(u_1))
     return col, u0
Ejemplo n.º 5
0
 def check_aabbs(self):
     out = []
     self.add_grid_bounding_boxes_to(out)
     check = [0, 0, 0, 0]
     if len(out) == 3:
         bb = out[2]
         if fops.gt(bb.min_x, self.x):
             check[2] = -1
         elif fops.lt(bb.max_x, self.x + 1):
             check[2] = 1
         if fops.gt(bb.min_z, self.z):
             check[3] = -1
         elif fops.lt(bb.max_z, self.z + 1):
             check[3] = 1
     bb = out[1]
     if fops.gt(bb.min_x, self.x):
         check[0] = -1
     elif fops.lt(bb.max_x, self.x + 1):
         check[0] = 1
     if fops.gt(bb.min_z, self.z):
         check[1] = -1
     elif fops.lt(bb.max_z, self.z + 1):
         check[1] = 1
     if check[2] != 0 or check[3] != 0:
         if check[0] != 0:
             check[2] = check[0]
         if check[1] != 0:
             check[3] = check[1]
         yield AABB.from_block_coords(self.x + check[2] * config.PLAYER_RADIUS, self.y + 0.5, self.z + check[3] * config.PLAYER_RADIUS)
     else:
         if check[0] != 0:
             yield AABB.from_block_coords(self.x + check[0] * config.PLAYER_RADIUS, self.y + 0.5, self.z)
         if check[1] != 0:
             yield AABB.from_block_coords(self.x, self.y + 0.5, self.z + check[1] * config.PLAYER_RADIUS)
Ejemplo n.º 6
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)
Ejemplo n.º 7
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)
Ejemplo n.º 8
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
Ejemplo n.º 9
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
Ejemplo n.º 10
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
Ejemplo n.º 11
0
 def check_aabbs(self):
     out = []
     self.add_grid_bounding_boxes_to(out)
     check = [0, 0, 0, 0]
     if len(out) == 3:
         bb = out[2]
         if fops.gt(bb.min_x, self.x):
             check[2] = -1
         elif fops.lt(bb.max_x, self.x + 1):
             check[2] = 1
         if fops.gt(bb.min_z, self.z):
             check[3] = -1
         elif fops.lt(bb.max_z, self.z + 1):
             check[3] = 1
     bb = out[1]
     if fops.gt(bb.min_x, self.x):
         check[0] = -1
     elif fops.lt(bb.max_x, self.x + 1):
         check[0] = 1
     if fops.gt(bb.min_z, self.z):
         check[1] = -1
     elif fops.lt(bb.max_z, self.z + 1):
         check[1] = 1
     if check[2] != 0 or check[3] != 0:
         if check[0] != 0:
             check[2] = check[0]
         if check[1] != 0:
             check[3] = check[1]
         yield AABB.from_block_coords(
             self.x + check[2] * config.PLAYER_RADIUS, self.y + 0.5,
             self.z + check[3] * config.PLAYER_RADIUS)
     else:
         if check[0] != 0:
             yield AABB.from_block_coords(
                 self.x + check[0] * config.PLAYER_RADIUS, self.y + 0.5,
                 self.z)
         if check[1] != 0:
             yield AABB.from_block_coords(
                 self.x, self.y + 0.5,
                 self.z + check[1] * config.PLAYER_RADIUS)
Ejemplo n.º 12
0
 def _tick(self):
     b_obj = self.bot.bot_object
     self.status = self.check_status(b_obj)
     if self.status != Status.running:
         return
     col_distance, col_bb = self.world.grid.min_collision_between(b_obj.aabb,
                                                                  self.target_space.bb_stand,
                                                                  horizontal=True,
                                                                  max_height=True)
     if self.bot.is_on_ladder(b_obj) or self.bot.is_in_water(b_obj):
         elev = self.target_space.bb_stand.min_y - b_obj.aabb.min_y
         if fops.gt(elev, 0):
             self.jump(b_obj)
             self.move(b_obj)
         elif fops.lt(elev, 0):
             if col_distance is None:
                 self.move(b_obj)
         else:
             self.move(b_obj)
     elif self.bot.is_standing(b_obj):
         if col_distance is None:
             self.move(b_obj)
         else:
             elev = self.target_space.bb_stand.min_y - b_obj.aabb.min_y
             if fops.lte(elev, 0):
                 self.move(b_obj)
             elif fops.gt(elev, 0) and fops.lte(elev, config.MAX_STEP_HEIGHT):
                 self.move(b_obj)
             elif fops.gt(elev, config.MAX_STEP_HEIGHT) and fops.lt(elev, config.MAX_JUMP_HEIGHT):
                 ticks_to_col = col_distance / self.bot.current_motion(b_obj)
                 ticks_to_jump = math.sqrt(2 * elev / config.G) * 20
                 if ticks_to_col < ticks_to_jump:
                     self.jump(b_obj)
                 self.move(b_obj)
             else:
                 raise Exception("move elevation error %s with collision %s" % (elev, col_distance))
     else:
         self.move(b_obj)
Ejemplo n.º 13
0
 def calculate_axis_offset(self, collidee, d, axis):
     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 d
     if d < 0 and fops.lte(collidee.maxs[axis], self.mins[axis]):
         dout = collidee.maxs[axis] - self.mins[axis]
         if fops.gt(dout, d):
             d = dout
     elif d > 0 and fops.gte(collidee.mins[axis], self.maxs[axis]):
         dout = collidee.mins[axis] - self.maxs[axis]
         if fops.lt(dout, d):
             d = dout
     return d
Ejemplo n.º 14
0
 def calculate_axis_offset(self, collidee, d, axis):
     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 d
     if d < 0 and fops.lte(collidee.maxs[axis], self.mins[axis]):
         dout = collidee.maxs[axis] - self.mins[axis]
         if fops.gt(dout, d):
             d = dout
     elif d > 0 and fops.gte(collidee.mins[axis], self.maxs[axis]):
         dout = collidee.mins[axis] - self.maxs[axis]
         if fops.lt(dout, d):
             d = dout
     return d
Ejemplo n.º 15
0
 def can_stand_between(self, gs, debug=False):
     if self.block.is_ladder_vine or gs.block.is_ladder_vine:
         return True
     if self.block.is_water or gs.block.is_water:
         return True
     if fops.gt(abs(self.platform.min_y - gs.platform.min_y), config.MAX_STEP_HEIGHT):
         return True
     stand_platform = self.platform.expand(config.PLAYER_BODY_DIAMETER - 0.09, 0, config.PLAYER_BODY_DIAMETER - 0.09)
     self.intersection = gs.stand_block.intersection_on_axes(
         stand_platform, x=True, z=True, debug=debug)
     if self.intersection is None:
         return False
     if self.stand_block.x != gs.stand_block.x and self.stand_block.z != gs.stand_block.z:
         if fops.lt(gs.platform.get_side('min', x=True, z=True), 0.5):
             return False
         else:
             return True
     else:
         return True
Ejemplo n.º 16
0
 def can_go_between(self, gs, update_to_bb_stand=False, debug=False):
     edge_cost = 0
     bb_stand = self.bb_stand
     other_bb_stand = gs.bb_stand
     if bb_stand.horizontal_distance(other_bb_stand) > config.HORIZONTAL_MOVE_DISTANCE_LIMIT:
         if debug:
             print 'horizontal distance too far', bb_stand.horizontal_distance(other_bb_stand)
         return False
     if fops.gt(bb_stand.min_y, other_bb_stand.min_y):
         if (bb_stand.min_y - other_bb_stand.min_y) > 3:
             return False
         elev = bb_stand.min_y - other_bb_stand.min_y
         elev_bb = other_bb_stand.extend_to(dy=elev)
         bb_from = bb_stand
         bb_to = other_bb_stand.offset(dy=elev)
     elif fops.lt(bb_stand.min_y, other_bb_stand.min_y):
         if fops.lte(bb_stand.grid_y + 2, other_bb_stand.min_y):
             if debug:
                 print 'over 2 high difference'
             return False
         elev = other_bb_stand.min_y - bb_stand.min_y
         in_water = self.grid.aabb_in_water(bb_stand)
         if in_water and \
                 other_bb_stand.grid_y > bb_stand.grid_y and \
                 fops.gt(other_bb_stand.min_y, other_bb_stand.grid_y) and \
                 not self.grid.aabb_in_water(bb_stand.shift(min_y=other_bb_stand.min_y)) and \
                 fops.gte(other_bb_stand.min_y - (bb_stand.grid_y + 1), config.MAX_WATER_JUMP_HEIGHT - 0.15):
             if debug:
                 print 'water cannot go'
             return False
         if self.grid.aabb_on_ladder(bb_stand) and \
                 other_bb_stand.grid_y > bb_stand.grid_y and \
                 fops.gt(other_bb_stand.min_y, other_bb_stand.grid_y) and \
                 not self.grid.aabb_on_ladder(bb_stand.shift(min_y=other_bb_stand.min_y)) and \
                 fops.gte(other_bb_stand.min_y - (bb_stand.grid_y + 1), config.MAX_VINE_JUMP_HEIGHT - 0.2):
             if debug:
                 print 'ladder cannot go'
             return False
         if fops.gt(elev, config.MAX_JUMP_HEIGHT) and not in_water:
             if debug:
                 print 'too high'
             return False
         if fops.lte(elev, config.MAX_STEP_HEIGHT):
             elev = config.MAX_STEP_HEIGHT
             aabbs = self.grid.aabbs_in(bb_stand.extend_to(0, elev, 0))
             for bb in aabbs:
                 elev = bb_stand.calculate_axis_offset(bb, elev, 1)
             if fops.lt(bb_stand.min_y + elev, other_bb_stand.min_y):
                 if debug:
                     print 'cannot make step'
                 return False
         elev_bb = bb_stand.extend_to(dy=elev)
         bb_from = bb_stand.offset(dy=elev)
         bb_to = other_bb_stand
     else:
         elev = 0
         elev_bb = None
         bb_from = bb_stand
         bb_to = other_bb_stand
     if elev_bb is not None:
         if self.grid.aabb_collides(elev_bb):
             if debug:
                 print 'elevation collision'
             return False
         if self.blocks_to_avoid(self.grid.blocks_in_aabb(elev_bb)):
             if debug:
                 print 'elevation hitting avoid block'
             return False
     if self.grid.collision_between(bb_from, bb_to, debug=debug):
         if debug:
             print 'horizontal collision'
         return False
     if self.blocks_to_avoid(self.grid.passing_blocks_between(bb_from, bb_to)):
         if debug:
             print 'hitting avoid block'
         return False
     edge_cost += config.COST_DIRECT * bb_from.horizontal_distance(bb_to)
     if not (fops.lte(elev, config.MAX_STEP_HEIGHT) and fops.gte(elev, -config.MAX_STEP_HEIGHT)):
         edge_cost += config.COST_FALL * \
             bb_from.horizontal_distance(bb_to)
         if elev < 0:
             edge_cost += config.COST_FALL * elev
         else:
             edge_cost += config.COST_JUMP
     self.edge_cost = edge_cost
     if update_to_bb_stand:
         gs.bb_stand = other_bb_stand
     return True
Ejemplo n.º 17
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