forked from Mirrorlandia_minetest/minetest
Add disable_jump to liquids and ladders (#7688)
Remove second nodedef check by improving the colliding node detection Also remove the 2nd check in old_move, correct standing node a bit
This commit is contained in:
parent
bd6f1cca9d
commit
e40be619f2
@ -170,8 +170,8 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
|
|||||||
std::vector<CollisionInfo> *collision_info)
|
std::vector<CollisionInfo> *collision_info)
|
||||||
{
|
{
|
||||||
if (!collision_info || collision_info->empty()) {
|
if (!collision_info || collision_info->empty()) {
|
||||||
// Node below the feet, update each ClientEnvironment::step()
|
// Node at feet position, update each ClientEnvironment::step()
|
||||||
m_standing_node = floatToInt(m_position, BS) - v3s16(0, 1, 0);
|
m_standing_node = floatToInt(m_position, BS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporary option for old move code
|
// Temporary option for old move code
|
||||||
@ -309,7 +309,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
|
|||||||
collision_info->push_back(colinfo);
|
collision_info->push_back(colinfo);
|
||||||
|
|
||||||
if (colinfo.type != COLLISION_NODE ||
|
if (colinfo.type != COLLISION_NODE ||
|
||||||
colinfo.new_speed.Y != 0 ||
|
colinfo.axis != COLLISION_AXIS_Y ||
|
||||||
(could_sneak && m_sneak_node_exists))
|
(could_sneak && m_sneak_node_exists))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -320,6 +320,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
|
|||||||
if (is_first || len < distance) {
|
if (is_first || len < distance) {
|
||||||
m_standing_node = colinfo.node_p;
|
m_standing_node = colinfo.node_p;
|
||||||
distance = len;
|
distance = len;
|
||||||
|
is_first = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -435,11 +436,11 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
|
|||||||
Check properties of the node on which the player is standing
|
Check properties of the node on which the player is standing
|
||||||
*/
|
*/
|
||||||
const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(m_standing_node));
|
const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(m_standing_node));
|
||||||
|
|
||||||
// Determine if jumping is possible
|
// Determine if jumping is possible
|
||||||
m_can_jump = (touching_ground && !in_liquid && !is_climbing)
|
m_disable_jump = itemgroup_get(f.groups, "disable_jump");
|
||||||
|| sneak_can_jump;
|
m_can_jump = ((touching_ground && !is_climbing)
|
||||||
if (itemgroup_get(f.groups, "disable_jump"))
|
|| sneak_can_jump) && !m_disable_jump;
|
||||||
m_can_jump = false;
|
|
||||||
|
|
||||||
// Jump key pressed while jumping off from a bouncy block
|
// Jump key pressed while jumping off from a bouncy block
|
||||||
if (m_can_jump && control.jump && itemgroup_get(f.groups, "bouncy") &&
|
if (m_can_jump && control.jump && itemgroup_get(f.groups, "bouncy") &&
|
||||||
@ -636,17 +637,13 @@ void LocalPlayer::applyControl(float dtime, Environment *env)
|
|||||||
setSpeed(speedJ);
|
setSpeed(speedJ);
|
||||||
m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::PLAYER_JUMP));
|
m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::PLAYER_JUMP));
|
||||||
}
|
}
|
||||||
}
|
} else if (in_liquid && !m_disable_jump) {
|
||||||
else if(in_liquid)
|
|
||||||
{
|
|
||||||
if (fast_climb)
|
if (fast_climb)
|
||||||
speedV.Y = movement_speed_fast;
|
speedV.Y = movement_speed_fast;
|
||||||
else
|
else
|
||||||
speedV.Y = movement_speed_walk;
|
speedV.Y = movement_speed_walk;
|
||||||
swimming_vertical = true;
|
swimming_vertical = true;
|
||||||
}
|
} else if (is_climbing && !m_disable_jump) {
|
||||||
else if(is_climbing)
|
|
||||||
{
|
|
||||||
if (fast_climb)
|
if (fast_climb)
|
||||||
speedV.Y = movement_speed_fast;
|
speedV.Y = movement_speed_fast;
|
||||||
else
|
else
|
||||||
@ -908,6 +905,12 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
|
|||||||
pos_max_d, m_collisionbox, player_stepheight, dtime,
|
pos_max_d, m_collisionbox, player_stepheight, dtime,
|
||||||
&position, &m_speed, accel_f);
|
&position, &m_speed, accel_f);
|
||||||
|
|
||||||
|
// Positition was slightly changed; update standing node pos
|
||||||
|
if (touching_ground)
|
||||||
|
m_standing_node = floatToInt(m_position - v3f(0, 0.1f * BS, 0), BS);
|
||||||
|
else
|
||||||
|
m_standing_node = floatToInt(m_position, BS);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If the player's feet touch the topside of any node, this is
|
If the player's feet touch the topside of any node, this is
|
||||||
set to true.
|
set to true.
|
||||||
@ -1048,11 +1051,13 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
|
|||||||
/*
|
/*
|
||||||
Check properties of the node on which the player is standing
|
Check properties of the node on which the player is standing
|
||||||
*/
|
*/
|
||||||
const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(getStandingNodePos()));
|
const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(
|
||||||
|
getStandingNodePos()));
|
||||||
|
|
||||||
// Determine if jumping is possible
|
// Determine if jumping is possible
|
||||||
m_can_jump = touching_ground && !in_liquid;
|
m_disable_jump = itemgroup_get(f.groups, "disable_jump");
|
||||||
if (itemgroup_get(f.groups, "disable_jump"))
|
m_can_jump = touching_ground && !m_disable_jump;
|
||||||
m_can_jump = false;
|
|
||||||
// Jump key pressed while jumping off from a bouncy block
|
// Jump key pressed while jumping off from a bouncy block
|
||||||
if (m_can_jump && control.jump && itemgroup_get(f.groups, "bouncy") &&
|
if (m_can_jump && control.jump && itemgroup_get(f.groups, "bouncy") &&
|
||||||
m_speed.Y >= -0.5 * BS) {
|
m_speed.Y >= -0.5 * BS) {
|
||||||
|
@ -183,6 +183,7 @@ private:
|
|||||||
// ***** End of variables for temporary option *****
|
// ***** End of variables for temporary option *****
|
||||||
|
|
||||||
bool m_can_jump = false;
|
bool m_can_jump = false;
|
||||||
|
bool m_disable_jump = false;
|
||||||
u16 m_breath = PLAYER_MAX_BREATH_DEFAULT;
|
u16 m_breath = PLAYER_MAX_BREATH_DEFAULT;
|
||||||
f32 m_yaw = 0.0f;
|
f32 m_yaw = 0.0f;
|
||||||
f32 m_pitch = 0.0f;
|
f32 m_pitch = 0.0f;
|
||||||
|
@ -59,7 +59,7 @@ struct NearbyCollisionInfo {
|
|||||||
// Checks for collision of a moving aabbox with a static aabbox
|
// Checks for collision of a moving aabbox with a static aabbox
|
||||||
// Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision
|
// Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision
|
||||||
// The time after which the collision occurs is stored in dtime.
|
// The time after which the collision occurs is stored in dtime.
|
||||||
int axisAlignedCollision(
|
CollisionAxis axisAlignedCollision(
|
||||||
const aabb3f &staticbox, const aabb3f &movingbox,
|
const aabb3f &staticbox, const aabb3f &movingbox,
|
||||||
const v3f &speed, f32 d, f32 *dtime)
|
const v3f &speed, f32 d, f32 *dtime)
|
||||||
{
|
{
|
||||||
@ -86,11 +86,11 @@ int axisAlignedCollision(
|
|||||||
(relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO) &&
|
(relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO) &&
|
||||||
(relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) &&
|
(relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) &&
|
||||||
(relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO))
|
(relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO))
|
||||||
return 0;
|
return COLLISION_AXIS_X;
|
||||||
}
|
}
|
||||||
else if(relbox.MinEdge.X > xsize)
|
else if(relbox.MinEdge.X > xsize)
|
||||||
{
|
{
|
||||||
return -1;
|
return COLLISION_AXIS_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(speed.X < 0) // Check for collision with X+ plane
|
else if(speed.X < 0) // Check for collision with X+ plane
|
||||||
@ -101,11 +101,11 @@ int axisAlignedCollision(
|
|||||||
(relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO) &&
|
(relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO) &&
|
||||||
(relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) &&
|
(relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) &&
|
||||||
(relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO))
|
(relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO))
|
||||||
return 0;
|
return COLLISION_AXIS_X;
|
||||||
}
|
}
|
||||||
else if(relbox.MaxEdge.X < 0)
|
else if(relbox.MaxEdge.X < 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return COLLISION_AXIS_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,11 +119,11 @@ int axisAlignedCollision(
|
|||||||
(relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) &&
|
(relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) &&
|
||||||
(relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) &&
|
(relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) &&
|
||||||
(relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO))
|
(relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO))
|
||||||
return 1;
|
return COLLISION_AXIS_Y;
|
||||||
}
|
}
|
||||||
else if(relbox.MinEdge.Y > ysize)
|
else if(relbox.MinEdge.Y > ysize)
|
||||||
{
|
{
|
||||||
return -1;
|
return COLLISION_AXIS_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(speed.Y < 0) // Check for collision with Y+ plane
|
else if(speed.Y < 0) // Check for collision with Y+ plane
|
||||||
@ -134,11 +134,11 @@ int axisAlignedCollision(
|
|||||||
(relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) &&
|
(relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) &&
|
||||||
(relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) &&
|
(relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) &&
|
||||||
(relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO))
|
(relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO))
|
||||||
return 1;
|
return COLLISION_AXIS_Y;
|
||||||
}
|
}
|
||||||
else if(relbox.MaxEdge.Y < 0)
|
else if(relbox.MaxEdge.Y < 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return COLLISION_AXIS_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,11 +152,11 @@ int axisAlignedCollision(
|
|||||||
(relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) &&
|
(relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) &&
|
||||||
(relbox.MinEdge.Y + speed.Y * (*dtime) < ysize) &&
|
(relbox.MinEdge.Y + speed.Y * (*dtime) < ysize) &&
|
||||||
(relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO))
|
(relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO))
|
||||||
return 2;
|
return COLLISION_AXIS_Z;
|
||||||
}
|
}
|
||||||
//else if(relbox.MinEdge.Z > zsize)
|
//else if(relbox.MinEdge.Z > zsize)
|
||||||
//{
|
//{
|
||||||
// return -1;
|
// return COLLISION_AXIS_NONE;
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
else if(speed.Z < 0) // Check for collision with Z+ plane
|
else if(speed.Z < 0) // Check for collision with Z+ plane
|
||||||
@ -167,15 +167,15 @@ int axisAlignedCollision(
|
|||||||
(relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) &&
|
(relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) &&
|
||||||
(relbox.MinEdge.Y + speed.Y * (*dtime) < ysize) &&
|
(relbox.MinEdge.Y + speed.Y * (*dtime) < ysize) &&
|
||||||
(relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO))
|
(relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO))
|
||||||
return 2;
|
return COLLISION_AXIS_Z;
|
||||||
}
|
}
|
||||||
//else if(relbox.MaxEdge.Z < 0)
|
//else if(relbox.MaxEdge.Z < 0)
|
||||||
//{
|
//{
|
||||||
// return -1;
|
// return COLLISION_AXIS_NONE;
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return COLLISION_AXIS_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function:
|
// Helper function:
|
||||||
@ -442,7 +442,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||||||
movingbox.MinEdge += *pos_f;
|
movingbox.MinEdge += *pos_f;
|
||||||
movingbox.MaxEdge += *pos_f;
|
movingbox.MaxEdge += *pos_f;
|
||||||
|
|
||||||
int nearest_collided = -1;
|
CollisionAxis nearest_collided = COLLISION_AXIS_NONE;
|
||||||
f32 nearest_dtime = dtime;
|
f32 nearest_dtime = dtime;
|
||||||
int nearest_boxindex = -1;
|
int nearest_boxindex = -1;
|
||||||
|
|
||||||
@ -457,7 +457,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||||||
|
|
||||||
// Find nearest collision of the two boxes (raytracing-like)
|
// Find nearest collision of the two boxes (raytracing-like)
|
||||||
f32 dtime_tmp;
|
f32 dtime_tmp;
|
||||||
int collided = axisAlignedCollision(box_info.box,
|
CollisionAxis collided = axisAlignedCollision(box_info.box,
|
||||||
movingbox, *speed_f, d, &dtime_tmp);
|
movingbox, *speed_f, d, &dtime_tmp);
|
||||||
|
|
||||||
if (collided == -1 || dtime_tmp >= nearest_dtime)
|
if (collided == -1 || dtime_tmp >= nearest_dtime)
|
||||||
@ -468,7 +468,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||||||
nearest_boxindex = boxindex;
|
nearest_boxindex = boxindex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nearest_collided == -1) {
|
if (nearest_collided == COLLISION_AXIS_NONE) {
|
||||||
// No collision with any collision box.
|
// No collision with any collision box.
|
||||||
*pos_f += *speed_f * dtime;
|
*pos_f += *speed_f * dtime;
|
||||||
dtime = 0; // Set to 0 to avoid "infinite" loop due to small FP numbers
|
dtime = 0; // Set to 0 to avoid "infinite" loop due to small FP numbers
|
||||||
@ -477,7 +477,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||||||
NearbyCollisionInfo &nearest_info = cinfo[nearest_boxindex];
|
NearbyCollisionInfo &nearest_info = cinfo[nearest_boxindex];
|
||||||
const aabb3f& cbox = nearest_info.box;
|
const aabb3f& cbox = nearest_info.box;
|
||||||
// Check for stairs.
|
// Check for stairs.
|
||||||
bool step_up = (nearest_collided != 1) && // must not be Y direction
|
bool step_up = (nearest_collided != COLLISION_AXIS_Y) && // must not be Y direction
|
||||||
(movingbox.MinEdge.Y < cbox.MaxEdge.Y) &&
|
(movingbox.MinEdge.Y < cbox.MaxEdge.Y) &&
|
||||||
(movingbox.MinEdge.Y + stepheight > cbox.MaxEdge.Y) &&
|
(movingbox.MinEdge.Y + stepheight > cbox.MaxEdge.Y) &&
|
||||||
(!wouldCollideWithCeiling(cinfo, movingbox,
|
(!wouldCollideWithCeiling(cinfo, movingbox,
|
||||||
@ -491,11 +491,11 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||||||
if (nearest_dtime < 0) {
|
if (nearest_dtime < 0) {
|
||||||
// Handle negative nearest_dtime (can be caused by the d allowance)
|
// Handle negative nearest_dtime (can be caused by the d allowance)
|
||||||
if (!step_up) {
|
if (!step_up) {
|
||||||
if (nearest_collided == 0)
|
if (nearest_collided == COLLISION_AXIS_X)
|
||||||
pos_f->X += speed_f->X * nearest_dtime;
|
pos_f->X += speed_f->X * nearest_dtime;
|
||||||
if (nearest_collided == 1)
|
if (nearest_collided == COLLISION_AXIS_Y)
|
||||||
pos_f->Y += speed_f->Y * nearest_dtime;
|
pos_f->Y += speed_f->Y * nearest_dtime;
|
||||||
if (nearest_collided == 2)
|
if (nearest_collided == COLLISION_AXIS_Z)
|
||||||
pos_f->Z += speed_f->Z * nearest_dtime;
|
pos_f->Z += speed_f->Z * nearest_dtime;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -522,19 +522,19 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||||||
// Special case: Handle stairs
|
// Special case: Handle stairs
|
||||||
nearest_info.is_step_up = true;
|
nearest_info.is_step_up = true;
|
||||||
is_collision = false;
|
is_collision = false;
|
||||||
} else if (nearest_collided == 0) { // X
|
} else if (nearest_collided == COLLISION_AXIS_X) {
|
||||||
if (fabs(speed_f->X) > BS * 3)
|
if (fabs(speed_f->X) > BS * 3)
|
||||||
speed_f->X *= bounce;
|
speed_f->X *= bounce;
|
||||||
else
|
else
|
||||||
speed_f->X = 0;
|
speed_f->X = 0;
|
||||||
result.collides = true;
|
result.collides = true;
|
||||||
} else if (nearest_collided == 1) { // Y
|
} else if (nearest_collided == COLLISION_AXIS_Y) {
|
||||||
if(fabs(speed_f->Y) > BS * 3)
|
if(fabs(speed_f->Y) > BS * 3)
|
||||||
speed_f->Y *= bounce;
|
speed_f->Y *= bounce;
|
||||||
else
|
else
|
||||||
speed_f->Y = 0;
|
speed_f->Y = 0;
|
||||||
result.collides = true;
|
result.collides = true;
|
||||||
} else if (nearest_collided == 2) { // Z
|
} else if (nearest_collided == COLLISION_AXIS_Z) {
|
||||||
if (fabs(speed_f->Z) > BS * 3)
|
if (fabs(speed_f->Z) > BS * 3)
|
||||||
speed_f->Z *= bounce;
|
speed_f->Z *= bounce;
|
||||||
else
|
else
|
||||||
@ -547,6 +547,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||||||
is_collision = false;
|
is_collision = false;
|
||||||
|
|
||||||
if (is_collision) {
|
if (is_collision) {
|
||||||
|
info.axis = nearest_collided;
|
||||||
result.collisions.push_back(info);
|
result.collisions.push_back(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,20 @@ enum CollisionType
|
|||||||
COLLISION_OBJECT,
|
COLLISION_OBJECT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CollisionAxis
|
||||||
|
{
|
||||||
|
COLLISION_AXIS_NONE = -1,
|
||||||
|
COLLISION_AXIS_X,
|
||||||
|
COLLISION_AXIS_Y,
|
||||||
|
COLLISION_AXIS_Z,
|
||||||
|
};
|
||||||
|
|
||||||
struct CollisionInfo
|
struct CollisionInfo
|
||||||
{
|
{
|
||||||
CollisionInfo() = default;
|
CollisionInfo() = default;
|
||||||
|
|
||||||
CollisionType type = COLLISION_NODE;
|
CollisionType type = COLLISION_NODE;
|
||||||
|
CollisionAxis axis = COLLISION_AXIS_NONE;
|
||||||
v3s16 node_p = v3s16(-32768,-32768,-32768); // COLLISION_NODE
|
v3s16 node_p = v3s16(-32768,-32768,-32768); // COLLISION_NODE
|
||||||
v3f old_speed;
|
v3f old_speed;
|
||||||
v3f new_speed;
|
v3f new_speed;
|
||||||
@ -66,7 +75,7 @@ collisionMoveResult collisionMoveSimple(Environment *env,IGameDef *gamedef,
|
|||||||
// Checks for collision of a moving aabbox with a static aabbox
|
// Checks for collision of a moving aabbox with a static aabbox
|
||||||
// Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision
|
// Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision
|
||||||
// dtime receives time until first collision, invalid if -1 is returned
|
// dtime receives time until first collision, invalid if -1 is returned
|
||||||
int axisAlignedCollision(
|
CollisionAxis axisAlignedCollision(
|
||||||
const aabb3f &staticbox, const aabb3f &movingbox,
|
const aabb3f &staticbox, const aabb3f &movingbox,
|
||||||
const v3f &speed, f32 d, f32 *dtime);
|
const v3f &speed, f32 d, f32 *dtime);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user