mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 17:57:02 +08:00
refactor(ecs): move entity physics to tick-based systems
Update PhysicalSystem and SpeedSystem to operate on entt::registry instead of individual components. Add TickVelocity for server creatures so movement is calculated per tick without frame delta time. LocalPlayer now implements its own client-side physics with collision detection.
This commit is contained in:
@@ -3,10 +3,17 @@
|
|||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
struct TickVelocity {
|
||||||
|
|
||||||
|
glm::vec3 value{0.0f};
|
||||||
|
// blocks/tick!!! -1 for in
|
||||||
|
glm::vec3 max{1.0f, -1.0f, 1.0f};
|
||||||
|
};
|
||||||
|
|
||||||
struct Velocity {
|
struct Velocity {
|
||||||
|
|
||||||
glm::vec3 value{0.0f};
|
glm::vec3 value{0.0f};
|
||||||
|
// blocks/second!!!
|
||||||
glm::vec3 max{4.5f, 7.5f, 7.5f};
|
glm::vec3 max{4.5f, 7.5f, 7.5f};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -23,4 +30,5 @@ struct Gravity {
|
|||||||
|
|
||||||
float value = DEFAULT_G;
|
float value = DEFAULT_G;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -8,7 +8,7 @@ namespace Cubed {
|
|||||||
struct BaseServerCreature {
|
struct BaseServerCreature {
|
||||||
Transform transform{};
|
Transform transform{};
|
||||||
|
|
||||||
Velocity velocity{};
|
TickVelocity velocity{};
|
||||||
|
|
||||||
Movement movement{};
|
Movement movement{};
|
||||||
|
|
||||||
|
|||||||
@@ -149,12 +149,14 @@ private:
|
|||||||
|
|
||||||
void update_direction();
|
void update_direction();
|
||||||
void update_lookup_block();
|
void update_lookup_block();
|
||||||
|
void update_move(float dt);
|
||||||
void update_move(float delta_time);
|
|
||||||
|
|
||||||
void update_player_chunk();
|
void update_player_chunk();
|
||||||
|
|
||||||
void play_walk_sound(float dt);
|
void play_walk_sound(float dt);
|
||||||
Gait compute_gait() const;
|
Gait compute_gait() const;
|
||||||
|
|
||||||
|
void update_speed(float dt);
|
||||||
|
std::tuple<bool, bool, bool> update_physical(float dt);
|
||||||
|
glm::vec3 get_move_distance(float dt);
|
||||||
};
|
};
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
|
|||||||
@@ -1,18 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Cubed/gameplay/ecs/movement.hpp"
|
#include "Cubed/gameplay/ecs/movement.hpp"
|
||||||
#include "Cubed/gameplay/ecs/state.hpp"
|
|
||||||
#include "Cubed/gameplay/ecs/transform.hpp"
|
#include "Cubed/gameplay/ecs/transform.hpp"
|
||||||
#include "Cubed/gameplay/world.hpp"
|
|
||||||
namespace Cubed {
|
|
||||||
|
|
||||||
|
#include <entt/entt.hpp>
|
||||||
|
namespace Cubed {
|
||||||
|
class ServerWorld;
|
||||||
class PhysicalSystem {
|
class PhysicalSystem {
|
||||||
public:
|
public:
|
||||||
static glm::vec3 get_move_distance(float dt, const Direction& d,
|
static glm::vec3 get_move_distance(const Direction& d,
|
||||||
const Velocity& v);
|
const TickVelocity& v);
|
||||||
|
|
||||||
static std::tuple<bool, bool, bool>
|
static void update(ServerWorld& world, entt::registry& registry);
|
||||||
update(float dt, World& world, glm::vec3& moved_pos, Velocity& v,
|
|
||||||
Direction& direction, MoveState& move_state, HitboxID hitbox);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Cubed/gameplay/ecs/movement.hpp"
|
#include <entt/entt.hpp>
|
||||||
#include "Cubed/gameplay/ecs/state.hpp"
|
|
||||||
#include "Cubed/gameplay/ecs/transform.hpp"
|
|
||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
class SpeedSystem {
|
class SpeedSystem {
|
||||||
public:
|
public:
|
||||||
static void update(float dt, Velocity& v, MoveState& move_state,
|
static void update(float dt, entt::registry& registry);
|
||||||
Movement& movement, Direction& direction,
|
|
||||||
const Gravity& g);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,12 +5,110 @@
|
|||||||
#include "Cubed/debug_collector.hpp"
|
#include "Cubed/debug_collector.hpp"
|
||||||
#include "Cubed/gameplay/client_world.hpp"
|
#include "Cubed/gameplay/client_world.hpp"
|
||||||
#include "Cubed/gameplay/hitbox_manager.hpp"
|
#include "Cubed/gameplay/hitbox_manager.hpp"
|
||||||
#include "Cubed/gameplay/systems/physical_system.hpp"
|
|
||||||
#include "Cubed/gameplay/systems/speed_system.hpp"
|
|
||||||
namespace {} // namespace
|
|
||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
LocalPlayer::LocalPlayer(ClientWorld& world) : m_world(world) {}
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool update_x(const glm::vec3& pos, const glm::vec3& distance,
|
||||||
|
ClientWorld& world, const Hitbox& box) {
|
||||||
|
glm::vec3 p = pos;
|
||||||
|
p.x += distance.x;
|
||||||
|
Hitbox b = box;
|
||||||
|
b.center += p;
|
||||||
|
glm::vec3 min = b.min();
|
||||||
|
glm::vec3 max = b.max();
|
||||||
|
int minx = std::floor(min.x);
|
||||||
|
int maxx = std::floor(max.x);
|
||||||
|
int miny = std::floor(min.y);
|
||||||
|
int maxy = std::floor(max.y);
|
||||||
|
int minz = std::floor(min.z);
|
||||||
|
int maxz = std::floor(max.z);
|
||||||
|
|
||||||
|
for (int x = minx; x <= maxx; ++x) {
|
||||||
|
for (int y = miny; y <= maxy; ++y) {
|
||||||
|
for (int z = minz; z <= maxz; ++z) {
|
||||||
|
glm::ivec3 block_pos{x, y, z};
|
||||||
|
if (!world.can_pass_block(block_pos)) {
|
||||||
|
Hitbox block_box = World::get_block_aabb(block_pos);
|
||||||
|
if (b.intersects(block_box)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool update_y(const glm::vec3& pos, const glm::vec3& distance,
|
||||||
|
ClientWorld& world, const Hitbox& box) {
|
||||||
|
glm::vec3 p = pos;
|
||||||
|
p.y += distance.y;
|
||||||
|
Hitbox b = box;
|
||||||
|
b.center += p;
|
||||||
|
glm::vec3 min = b.min();
|
||||||
|
glm::vec3 max = b.max();
|
||||||
|
int minx = std::floor(min.x);
|
||||||
|
int maxx = std::floor(max.x);
|
||||||
|
int miny = std::floor(min.y);
|
||||||
|
int maxy = std::floor(max.y);
|
||||||
|
int minz = std::floor(min.z);
|
||||||
|
int maxz = std::floor(max.z);
|
||||||
|
|
||||||
|
for (int x = minx; x <= maxx; ++x) {
|
||||||
|
for (int y = miny; y <= maxy; ++y) {
|
||||||
|
for (int z = minz; z <= maxz; ++z) {
|
||||||
|
glm::ivec3 block_pos{x, y, z};
|
||||||
|
if (!world.can_pass_block(block_pos)) {
|
||||||
|
Hitbox block_box = World::get_block_aabb(block_pos);
|
||||||
|
if (b.intersects(block_box)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool update_z(const glm::vec3& pos, const glm::vec3& distance,
|
||||||
|
ClientWorld& world, const Hitbox& box) {
|
||||||
|
glm::vec3 p = pos;
|
||||||
|
p.z += distance.z;
|
||||||
|
Hitbox b = box;
|
||||||
|
b.center += p;
|
||||||
|
glm::vec3 min = b.min();
|
||||||
|
glm::vec3 max = b.max();
|
||||||
|
int minx = std::floor(min.x);
|
||||||
|
int maxx = std::floor(max.x);
|
||||||
|
int miny = std::floor(min.y);
|
||||||
|
int maxy = std::floor(max.y);
|
||||||
|
int minz = std::floor(min.z);
|
||||||
|
int maxz = std::floor(max.z);
|
||||||
|
|
||||||
|
for (int x = minx; x <= maxx; ++x) {
|
||||||
|
for (int y = miny; y <= maxy; ++y) {
|
||||||
|
for (int z = minz; z <= maxz; ++z) {
|
||||||
|
glm::ivec3 block_pos{x, y, z};
|
||||||
|
if (!world.can_pass_block(block_pos)) {
|
||||||
|
Hitbox block_box = World::get_block_aabb(block_pos);
|
||||||
|
if (b.intersects(block_box)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
LocalPlayer::LocalPlayer(ClientWorld& world) : m_world(world) {
|
||||||
|
|
||||||
|
m_hitbox = HitboxManager::instance().get_hitbox_id("cubed:player");
|
||||||
|
}
|
||||||
LocalPlayer::~LocalPlayer() {}
|
LocalPlayer::~LocalPlayer() {}
|
||||||
|
|
||||||
const glm::vec3& LocalPlayer::get_front() const { return m_front; }
|
const glm::vec3& LocalPlayer::get_front() const { return m_front; }
|
||||||
@@ -333,9 +431,9 @@ LocalPlayer::get_hotbar() const {
|
|||||||
return m_hotbar;
|
return m_hotbar;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalPlayer::update_move(float delta_time) {
|
void LocalPlayer::update_move(float dt) {
|
||||||
// if frame rate less than 1 frame per second, don't update
|
// if frame rate less than 1 frame per second, don't update
|
||||||
if (delta_time > 1.0f) {
|
if (dt > 1.0f) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,7 +441,7 @@ void LocalPlayer::update_move(float delta_time) {
|
|||||||
m_sprinting = false;
|
m_sprinting = false;
|
||||||
}
|
}
|
||||||
if (space_on) {
|
if (space_on) {
|
||||||
space_on_time += delta_time;
|
space_on_time += dt;
|
||||||
if (space_on_time >= MAX_SPACE_ON_TIME) {
|
if (space_on_time >= MAX_SPACE_ON_TIME) {
|
||||||
space_on = false;
|
space_on = false;
|
||||||
space_on_time = 0.0f;
|
space_on_time = 0.0f;
|
||||||
@@ -360,8 +458,7 @@ void LocalPlayer::update_move(float delta_time) {
|
|||||||
glm::vec3{m_max_run_speed, m_max_y_speed, m_max_run_speed};
|
glm::vec3{m_max_run_speed, m_max_y_speed, m_max_run_speed};
|
||||||
}
|
}
|
||||||
|
|
||||||
SpeedSystem::update(delta_time, m_velocity, m_move_state, m_movement,
|
update_speed(dt);
|
||||||
m_direction, m_gravity);
|
|
||||||
|
|
||||||
update_direction();
|
update_direction();
|
||||||
|
|
||||||
@@ -374,12 +471,9 @@ void LocalPlayer::update_move(float delta_time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_game_mode == SPECTATOR) {
|
if (m_game_mode == SPECTATOR) {
|
||||||
player_pos += PhysicalSystem::get_move_distance(delta_time, m_direction,
|
player_pos += get_move_distance(dt);
|
||||||
m_velocity);
|
|
||||||
} else {
|
} else {
|
||||||
auto [x, y, z] =
|
auto [x, y, z] = update_physical(dt);
|
||||||
PhysicalSystem::update(delta_time, m_world, player_pos, m_velocity,
|
|
||||||
m_direction, m_move_state, m_hitbox);
|
|
||||||
if (!x || !z) {
|
if (!x || !z) {
|
||||||
m_sprinting = false;
|
m_sprinting = false;
|
||||||
}
|
}
|
||||||
@@ -406,7 +500,7 @@ void LocalPlayer::update_move(float delta_time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto& [key, timer] : m_timers) {
|
for (auto& [key, timer] : m_timers) {
|
||||||
timer.update(delta_time);
|
timer.update(dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -593,6 +687,96 @@ void LocalPlayer::init(std::string_view name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LocalPlayer::update_speed(float dt) {
|
||||||
|
// calculate speed
|
||||||
|
auto& v = m_velocity;
|
||||||
|
if (m_move_state.forward || m_move_state.back || m_move_state.left ||
|
||||||
|
m_move_state.right) {
|
||||||
|
m_direction.value = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
v.value.x += m_movement.acceleration * dt;
|
||||||
|
v.value.z += m_movement.acceleration * dt;
|
||||||
|
if (v.value.x > v.max.x) {
|
||||||
|
v.value.x = v.max.x;
|
||||||
|
}
|
||||||
|
if (v.value.z > v.max.z) {
|
||||||
|
v.value.z = v.max.z;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
v.value.x += -m_movement.deceleration * dt;
|
||||||
|
v.value.z += -m_movement.deceleration * dt;
|
||||||
|
if (v.value.z < 0.0f) {
|
||||||
|
v.value.z = 0.0f;
|
||||||
|
}
|
||||||
|
if (v.value.x < 0.0f) {
|
||||||
|
v.value.x = 0.0f;
|
||||||
|
}
|
||||||
|
if (v.value.z < 0.0f && v.value.x < 0.0f) {
|
||||||
|
m_direction.value = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_move_state.is_fly) {
|
||||||
|
if (m_move_state.up) {
|
||||||
|
v.value.y = v.max.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_move_state.down) {
|
||||||
|
v.value.y = -v.max.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_move_state.down && !m_move_state.up) {
|
||||||
|
v.value.y = 0.0f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (m_move_state.up && m_move_state.can_up) {
|
||||||
|
v.value.y = m_movement.jump_power;
|
||||||
|
m_move_state.can_up = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
v.value.y += -m_gravity.value * dt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<bool, bool, bool> LocalPlayer::update_physical(float dt) {
|
||||||
|
|
||||||
|
auto distance = get_move_distance(dt);
|
||||||
|
auto box = HitboxManager::hitbox(m_hitbox);
|
||||||
|
bool x = false;
|
||||||
|
bool y = false;
|
||||||
|
bool z = false;
|
||||||
|
if (update_x(m_pos.value, distance, m_world, box.box)) {
|
||||||
|
m_pos.value.x += distance.x;
|
||||||
|
x = true;
|
||||||
|
} else {
|
||||||
|
m_velocity.value.x = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update_y(m_pos.value, distance, m_world, box.box)) {
|
||||||
|
m_pos.value.y += distance.y;
|
||||||
|
y = true;
|
||||||
|
} else {
|
||||||
|
m_velocity.value.y = 0.0f;
|
||||||
|
if (distance.y < 0) {
|
||||||
|
m_move_state.can_up = true;
|
||||||
|
m_move_state.is_fly = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update_z(m_pos.value, distance, m_world, box.box)) {
|
||||||
|
m_pos.value.z += distance.z;
|
||||||
|
z = true;
|
||||||
|
} else {
|
||||||
|
m_velocity.value.z = 0.0f;
|
||||||
|
}
|
||||||
|
return {x, y, z};
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 LocalPlayer::get_move_distance(float dt) {
|
||||||
|
const auto& d = m_direction;
|
||||||
|
const auto& v = m_velocity;
|
||||||
|
return glm::vec3{d.value.x * v.value.x * dt, v.value.y * dt,
|
||||||
|
d.value.z * v.value.z * dt};
|
||||||
|
}
|
||||||
|
|
||||||
bool LocalPlayer::is_underwater() const { return m_underwater; }
|
bool LocalPlayer::is_underwater() const { return m_underwater; }
|
||||||
void LocalPlayer::set_underwater(bool u) { m_underwater = u; }
|
void LocalPlayer::set_underwater(bool u) { m_underwater = u; }
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
#include "Cubed/gameplay/systems/physical_system.hpp"
|
#include "Cubed/gameplay/systems/physical_system.hpp"
|
||||||
|
|
||||||
|
#include "Cubed/gameplay/ecs/server_entity.hpp"
|
||||||
#include "Cubed/gameplay/hitbox_manager.hpp"
|
#include "Cubed/gameplay/hitbox_manager.hpp"
|
||||||
|
#include "Cubed/gameplay/server_world.hpp"
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool update_x(const glm::vec3& pos, const glm::vec3& distance, World& world,
|
bool update_x(const glm::vec3& pos, const glm::vec3& distance,
|
||||||
const Hitbox& box) {
|
ServerWorld& world, const Hitbox& box) {
|
||||||
glm::vec3 p = pos;
|
glm::vec3 p = pos;
|
||||||
p.x += distance.x;
|
p.x += distance.x;
|
||||||
Hitbox b = box;
|
Hitbox b = box;
|
||||||
@@ -36,8 +38,8 @@ bool update_x(const glm::vec3& pos, const glm::vec3& distance, World& world,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update_y(const glm::vec3& pos, const glm::vec3& distance, World& world,
|
bool update_y(const glm::vec3& pos, const glm::vec3& distance,
|
||||||
const Hitbox& box) {
|
ServerWorld& world, const Hitbox& box) {
|
||||||
glm::vec3 p = pos;
|
glm::vec3 p = pos;
|
||||||
p.y += distance.y;
|
p.y += distance.y;
|
||||||
Hitbox b = box;
|
Hitbox b = box;
|
||||||
@@ -67,8 +69,8 @@ bool update_y(const glm::vec3& pos, const glm::vec3& distance, World& world,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update_z(const glm::vec3& pos, const glm::vec3& distance, World& world,
|
bool update_z(const glm::vec3& pos, const glm::vec3& distance,
|
||||||
const Hitbox& box) {
|
ServerWorld& world, const Hitbox& box) {
|
||||||
glm::vec3 p = pos;
|
glm::vec3 p = pos;
|
||||||
p.z += distance.z;
|
p.z += distance.z;
|
||||||
Hitbox b = box;
|
Hitbox b = box;
|
||||||
@@ -100,45 +102,41 @@ bool update_z(const glm::vec3& pos, const glm::vec3& distance, World& world,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::tuple<bool, bool, bool>
|
void PhysicalSystem::update(ServerWorld& world, entt::registry& registry) {
|
||||||
PhysicalSystem::update(float dt, World& world, glm::vec3& moved_pos,
|
|
||||||
Velocity& v, Direction& direction, MoveState& move_state,
|
|
||||||
HitboxID hitbox) {
|
|
||||||
auto distance = get_move_distance(dt, direction, v);
|
|
||||||
auto box = HitboxManager::hitbox(hitbox);
|
|
||||||
bool x = false;
|
|
||||||
bool y = false;
|
|
||||||
bool z = false;
|
|
||||||
if (update_x(moved_pos, distance, world, box.box)) {
|
|
||||||
moved_pos.x += distance.x;
|
|
||||||
x = true;
|
|
||||||
} else {
|
|
||||||
v.value.x = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (update_y(moved_pos, distance, world, box.box)) {
|
auto view = registry.view<BaseServerCreature>();
|
||||||
moved_pos.y += distance.y;
|
for (auto e : view) {
|
||||||
y = true;
|
auto& creature = view.get<BaseServerCreature>(e);
|
||||||
} else {
|
auto distance =
|
||||||
v.value.y = 0.0f;
|
get_move_distance(creature.direction, creature.velocity);
|
||||||
if (distance.y < 0) {
|
auto box = HitboxManager::hitbox(creature.hitbox);
|
||||||
move_state.can_up = true;
|
auto& pos = creature.transform.position.value;
|
||||||
move_state.is_fly = false;
|
auto& v = creature.velocity;
|
||||||
|
if (update_x(pos, distance, world, box.box)) {
|
||||||
|
pos.x += distance.x;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
v.value.x = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update_y(pos, distance, world, box.box)) {
|
||||||
|
pos.y += distance.y;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
v.value.y = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update_z(pos, distance, world, box.box)) {
|
||||||
|
pos.z += distance.z;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
v.value.z = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update_z(moved_pos, distance, world, box.box)) {
|
|
||||||
moved_pos.z += distance.z;
|
|
||||||
z = true;
|
|
||||||
} else {
|
|
||||||
v.value.z = 0.0f;
|
|
||||||
}
|
|
||||||
return {x, y, z};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 PhysicalSystem::get_move_distance(float dt, const Direction& d,
|
glm::vec3 PhysicalSystem::get_move_distance(const Direction& d,
|
||||||
const Velocity& v) {
|
const TickVelocity& v) {
|
||||||
return glm::vec3{d.value.x * v.value.x * dt, v.value.y * dt,
|
return glm::vec3{d.value.x * v.value.x, v.value.y, d.value.z * v.value.z};
|
||||||
d.value.z * v.value.z * dt};
|
|
||||||
}
|
}
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -1,54 +1,24 @@
|
|||||||
#include "Cubed/gameplay/systems/speed_system.hpp"
|
#include "Cubed/gameplay/systems/speed_system.hpp"
|
||||||
|
|
||||||
|
#include "Cubed/gameplay/ecs/ai_struct.hpp"
|
||||||
|
#include "Cubed/gameplay/ecs/server_entity.hpp"
|
||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
void SpeedSystem::update(float dt, Velocity& v, MoveState& move_state,
|
void SpeedSystem::update(float dt, entt::registry& registry) {
|
||||||
Movement& movement, Direction& direction,
|
auto view = registry.view<BaseServerCreature, MoveBoost>();
|
||||||
const Gravity& g) {
|
|
||||||
// calculate speed
|
|
||||||
if (move_state.forward || move_state.back || move_state.left ||
|
|
||||||
move_state.right) {
|
|
||||||
direction.value = glm::vec3(0.0f, 0.0f, 0.0f);
|
|
||||||
v.value.x += movement.acceleration * dt;
|
|
||||||
v.value.z += movement.acceleration * dt;
|
|
||||||
if (v.value.x > v.max.x) {
|
|
||||||
v.value.x = v.max.x;
|
|
||||||
}
|
|
||||||
if (v.value.z > v.max.z) {
|
|
||||||
v.value.z = v.max.z;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v.value.x += -movement.deceleration * dt;
|
|
||||||
v.value.z += -movement.deceleration * dt;
|
|
||||||
if (v.value.z < 0.0f) {
|
|
||||||
v.value.z = 0.0f;
|
|
||||||
}
|
|
||||||
if (v.value.x < 0.0f) {
|
|
||||||
v.value.x = 0.0f;
|
|
||||||
}
|
|
||||||
if (v.value.z < 0.0f && v.value.x < 0.0f) {
|
|
||||||
direction.value = glm::vec3(0.0f, 0.0f, 0.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (move_state.is_fly) {
|
|
||||||
if (move_state.up) {
|
|
||||||
v.value.y = v.max.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (move_state.down) {
|
for (auto e : view) {
|
||||||
v.value.y = -v.max.y;
|
auto [creature, moveboost] = view.get<BaseServerCreature, MoveBoost>(e);
|
||||||
|
if (moveboost.count <= moveboost.duration) {
|
||||||
|
++moveboost.count;
|
||||||
|
creature.velocity.value +=
|
||||||
|
creature.direction.value * creature.movement.acceleration;
|
||||||
|
} else {
|
||||||
|
creature.velocity.value -=
|
||||||
|
creature.direction.value * creature.movement.deceleration;
|
||||||
}
|
}
|
||||||
|
creature.velocity.value.y = creature.gravity.value * dt;
|
||||||
if (!move_state.down && !move_state.up) {
|
|
||||||
v.value.y = 0.0f;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (move_state.up && move_state.can_up) {
|
|
||||||
v.value.y = movement.jump_power;
|
|
||||||
move_state.can_up = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
v.value.y += -g.value * dt;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user