refactor PlayerController
This commit is contained in:
parent
8eda26f171
commit
8a4f1e16f3
@ -49,9 +49,9 @@ LevelScreen::LevelScreen(Engine& engine, std::unique_ptr<Level> levelPtr)
|
||||
std::make_unique<LevelController>(&engine, std::move(levelPtr), player);
|
||||
playerController = std::make_unique<PlayerController>(
|
||||
settings,
|
||||
level,
|
||||
player,
|
||||
controller->getBlocksController()
|
||||
*level,
|
||||
*player,
|
||||
*controller->getBlocksController()
|
||||
);
|
||||
|
||||
frontend = std::make_unique<LevelFrontend>(
|
||||
|
||||
@ -41,20 +41,20 @@ const float C_ZOOM = 0.1f;
|
||||
const float CROUCH_SHIFT_Y = -0.2f;
|
||||
|
||||
CameraControl::CameraControl(
|
||||
Player* player, const CameraSettings& settings
|
||||
Player& player, const CameraSettings& settings
|
||||
)
|
||||
: player(player),
|
||||
camera(player->fpCamera),
|
||||
camera(player.fpCamera),
|
||||
settings(settings),
|
||||
offset(0.0f, 0.7f, 0.0f) {
|
||||
}
|
||||
|
||||
void CameraControl::refresh() {
|
||||
camera->position = player->getPosition() + offset;
|
||||
camera->position = player.getPosition() + offset;
|
||||
}
|
||||
|
||||
void CameraControl::updateMouse(PlayerInput& input) {
|
||||
glm::vec3& cam = player->cam;
|
||||
glm::vec3& cam = player.cam;
|
||||
|
||||
float sensitivity =
|
||||
(input.zoom ? settings.sensitivity.get() / 4.f
|
||||
@ -131,28 +131,29 @@ void CameraControl::updateFovEffects(
|
||||
// more extensible but uglier
|
||||
void CameraControl::switchCamera() {
|
||||
const std::vector<std::shared_ptr<Camera>> playerCameras {
|
||||
camera, player->tpCamera, player->spCamera};
|
||||
camera, player.tpCamera, player.spCamera
|
||||
};
|
||||
|
||||
auto index = std::distance(
|
||||
playerCameras.begin(),
|
||||
std::find_if(
|
||||
playerCameras.begin(),
|
||||
playerCameras.end(),
|
||||
[=](auto ptr) { return ptr.get() == player->currentCamera.get(); }
|
||||
[this](auto& ptr) { return ptr.get() == player.currentCamera.get(); }
|
||||
)
|
||||
);
|
||||
if (static_cast<size_t>(index) != playerCameras.size()) {
|
||||
index = (index + 1) % playerCameras.size();
|
||||
player->currentCamera = playerCameras.at(index);
|
||||
player.currentCamera = playerCameras.at(index);
|
||||
} else {
|
||||
player->currentCamera = camera;
|
||||
player.currentCamera = camera;
|
||||
}
|
||||
}
|
||||
|
||||
void CameraControl::update(PlayerInput input, float delta, Chunks* chunks) {
|
||||
void CameraControl::update(PlayerInput input, float delta, Chunks& chunks) {
|
||||
offset = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
if (auto hitbox = player->getHitbox()) {
|
||||
if (auto hitbox = player.getHitbox()) {
|
||||
offset.y += hitbox->halfsize.y * (0.7f / 0.9f);
|
||||
if (settings.shaking.get() && !input.cheat) {
|
||||
offset += updateCameraShaking(*hitbox, delta);
|
||||
@ -165,38 +166,38 @@ void CameraControl::update(PlayerInput input, float delta, Chunks* chunks) {
|
||||
switchCamera();
|
||||
}
|
||||
|
||||
auto spCamera = player->spCamera;
|
||||
auto tpCamera = player->tpCamera;
|
||||
auto& spCamera = player.spCamera;
|
||||
auto& tpCamera = player.tpCamera;
|
||||
|
||||
refresh();
|
||||
|
||||
camera->updateVectors();
|
||||
if (player->currentCamera == spCamera) {
|
||||
if (player.currentCamera == spCamera) {
|
||||
spCamera->position =
|
||||
chunks->rayCastToObstacle(camera->position, camera->front, 3.0f) -
|
||||
chunks.rayCastToObstacle(camera->position, camera->front, 3.0f) -
|
||||
0.4f * camera->front;
|
||||
spCamera->dir = -camera->dir;
|
||||
spCamera->front = -camera->front;
|
||||
spCamera->right = -camera->right;
|
||||
} else if (player->currentCamera == tpCamera) {
|
||||
} else if (player.currentCamera == tpCamera) {
|
||||
tpCamera->position =
|
||||
chunks->rayCastToObstacle(camera->position, -camera->front, 3.0f) +
|
||||
chunks.rayCastToObstacle(camera->position, -camera->front, 3.0f) +
|
||||
0.4f * camera->front;
|
||||
tpCamera->dir = camera->dir;
|
||||
tpCamera->front = camera->front;
|
||||
tpCamera->right = camera->right;
|
||||
}
|
||||
if (player->currentCamera == spCamera ||
|
||||
player->currentCamera == tpCamera || player->currentCamera == camera) {
|
||||
player->currentCamera->setFov(glm::radians(settings.fov.get()));
|
||||
if (player.currentCamera == spCamera ||
|
||||
player.currentCamera == tpCamera || player.currentCamera == camera) {
|
||||
player.currentCamera->setFov(glm::radians(settings.fov.get()));
|
||||
}
|
||||
}
|
||||
|
||||
PlayerController::PlayerController(
|
||||
const EngineSettings& settings,
|
||||
Level* level,
|
||||
Player* player,
|
||||
BlocksController* blocksController
|
||||
Level& level,
|
||||
Player& player,
|
||||
BlocksController& blocksController
|
||||
)
|
||||
: settings(settings),
|
||||
level(level),
|
||||
@ -214,14 +215,14 @@ void PlayerController::onFootstep(const Hitbox& hitbox) {
|
||||
int x = std::floor(pos.x + half.x * offsetX);
|
||||
int y = std::floor(pos.y - half.y * 1.1f);
|
||||
int z = std::floor(pos.z + half.z * offsetZ);
|
||||
auto vox = player->chunks->get(x, y, z);
|
||||
auto vox = player.chunks->get(x, y, z);
|
||||
if (vox) {
|
||||
auto& def = level->content->getIndices()->blocks.require(vox->id);
|
||||
auto& def = level.content->getIndices()->blocks.require(vox->id);
|
||||
if (!def.obstacle) {
|
||||
continue;
|
||||
}
|
||||
blocksController->onBlockInteraction(
|
||||
player,
|
||||
blocksController.onBlockInteraction(
|
||||
&player,
|
||||
glm::ivec3(x, y, z),
|
||||
def,
|
||||
BlockInteraction::step
|
||||
@ -233,7 +234,7 @@ void PlayerController::onFootstep(const Hitbox& hitbox) {
|
||||
}
|
||||
|
||||
void PlayerController::updateFootsteps(float delta) {
|
||||
auto hitbox = player->getHitbox();
|
||||
auto hitbox = player.getHitbox();
|
||||
if (hitbox && hitbox->grounded) {
|
||||
const glm::vec3& vel = hitbox->velocity;
|
||||
float f = glm::length(glm::vec2(vel.x, vel.z));
|
||||
@ -250,7 +251,7 @@ void PlayerController::updateFootsteps(float delta) {
|
||||
void PlayerController::update(float delta, bool input) {
|
||||
if (input) {
|
||||
updateKeyboard();
|
||||
player->updateSelectedEntity();
|
||||
player.updateSelectedEntity();
|
||||
} else {
|
||||
resetKeyboard();
|
||||
}
|
||||
@ -265,12 +266,12 @@ void PlayerController::postUpdate(float delta, bool input, bool pause) {
|
||||
if (!pause && input) {
|
||||
camControl.updateMouse(this->input);
|
||||
}
|
||||
player->postUpdate();
|
||||
camControl.update(this->input, pause ? 0.0f : delta, player->chunks.get());
|
||||
player.postUpdate();
|
||||
camControl.update(this->input, pause ? 0.0f : delta, *player.chunks);
|
||||
if (input) {
|
||||
updateInteraction(delta);
|
||||
} else {
|
||||
player->selection = {};
|
||||
player.selection = {};
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,8 +303,8 @@ void PlayerController::resetKeyboard() {
|
||||
}
|
||||
|
||||
void PlayerController::updatePlayer(float delta) {
|
||||
player->updateEntity();
|
||||
player->updateInput(input, delta);
|
||||
player.updateEntity();
|
||||
player.updateInput(input, delta);
|
||||
}
|
||||
|
||||
static int determine_rotation(
|
||||
@ -339,16 +340,20 @@ static int determine_rotation(
|
||||
}
|
||||
|
||||
static void pick_block(
|
||||
ContentIndices* indices, Chunks* chunks, Player* player, int x, int y, int z
|
||||
ContentIndices* indices,
|
||||
const Block& block,
|
||||
Player& player,
|
||||
int x,
|
||||
int y,
|
||||
int z
|
||||
) {
|
||||
auto& block = indices->blocks.require(chunks->get(x, y, z)->id);
|
||||
itemid_t id = block.rt.pickingItem;
|
||||
auto inventory = player->getInventory();
|
||||
auto inventory = player.getInventory();
|
||||
size_t slotid = inventory->findSlotByItem(id, 0, 10);
|
||||
if (slotid == Inventory::npos) {
|
||||
slotid = player->getChosenSlot();
|
||||
slotid = player.getChosenSlot();
|
||||
} else {
|
||||
player->setChosenSlot(slotid);
|
||||
player.setChosenSlot(slotid);
|
||||
}
|
||||
ItemStack& stack = inventory->getSlot(slotid);
|
||||
if (stack.getItemId() != id) {
|
||||
@ -357,10 +362,10 @@ static void pick_block(
|
||||
}
|
||||
|
||||
voxel* PlayerController::updateSelection(float maxDistance) {
|
||||
auto indices = level->content->getIndices();
|
||||
auto& chunks = *player->chunks;
|
||||
auto camera = player->fpCamera.get();
|
||||
auto& selection = player->selection;
|
||||
auto indices = level.content->getIndices();
|
||||
auto& chunks = *player.chunks;
|
||||
auto camera = player.fpCamera.get();
|
||||
auto& selection = player.selection;
|
||||
|
||||
glm::vec3 end;
|
||||
glm::ivec3 iend;
|
||||
@ -374,8 +379,8 @@ voxel* PlayerController::updateSelection(float maxDistance) {
|
||||
auto prevEntity = selection.entity;
|
||||
selection.entity = ENTITY_NONE;
|
||||
selection.actualPosition = iend;
|
||||
if (auto result = level->entities->rayCast(
|
||||
camera->position, camera->front, maxDistance, player->getEntity()
|
||||
if (auto result = level.entities->rayCast(
|
||||
camera->position, camera->front, maxDistance, player.getEntity()
|
||||
)) {
|
||||
selection.entity = result->entity;
|
||||
selection.hitPosition =
|
||||
@ -386,13 +391,13 @@ voxel* PlayerController::updateSelection(float maxDistance) {
|
||||
}
|
||||
if (selection.entity != prevEntity) {
|
||||
if (prevEntity != ENTITY_NONE) {
|
||||
if (auto pentity = level->entities->get(prevEntity)) {
|
||||
scripting::on_aim_off(*pentity, player);
|
||||
if (auto pentity = level.entities->get(prevEntity)) {
|
||||
scripting::on_aim_off(*pentity, &player);
|
||||
}
|
||||
}
|
||||
if (selection.entity != ENTITY_NONE) {
|
||||
if (auto pentity = level->entities->get(selection.entity)) {
|
||||
scripting::on_aim_on(*pentity, player);
|
||||
if (auto pentity = level.entities->get(selection.entity)) {
|
||||
scripting::on_aim_on(*pentity, &player);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -420,16 +425,16 @@ voxel* PlayerController::updateSelection(float maxDistance) {
|
||||
}
|
||||
|
||||
void PlayerController::processRightClick(const Block& def, const Block& target) {
|
||||
const auto& selection = player->selection;
|
||||
auto& chunks = *player->chunks;
|
||||
auto camera = player->fpCamera.get();
|
||||
const auto& selection = player.selection;
|
||||
auto& chunks = *player.chunks;
|
||||
auto camera = player.fpCamera.get();
|
||||
|
||||
blockstate state {};
|
||||
state.rotation = determine_rotation(&def, selection.normal, camera->dir);
|
||||
|
||||
if (!input.shift && target.rt.funcsset.oninteract) {
|
||||
if (scripting::on_block_interact(
|
||||
player, target, selection.actualPosition
|
||||
&player, target, selection.actualPosition
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
@ -445,7 +450,7 @@ void PlayerController::processRightClick(const Block& def, const Block& target)
|
||||
if (def.obstacle) {
|
||||
const auto& hitboxes = def.rt.hitboxes[state.rotation];
|
||||
for (const AABB& blockAABB : hitboxes) {
|
||||
if (level->entities->hasBlockingInside(blockAABB.translated(coord))) {
|
||||
if (level.entities->hasBlockingInside(blockAABB.translated(coord))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -466,12 +471,12 @@ void PlayerController::processRightClick(const Block& def, const Block& target)
|
||||
}
|
||||
}
|
||||
if (chosenBlock != vox->id && chosenBlock) {
|
||||
if (!player->isInfiniteItems()) {
|
||||
auto& slot = player->getInventory()->getSlot(player->getChosenSlot());
|
||||
if (!player.isInfiniteItems()) {
|
||||
auto& slot = player.getInventory()->getSlot(player.getChosenSlot());
|
||||
slot.setCount(slot.getCount()-1);
|
||||
}
|
||||
blocksController->placeBlock(
|
||||
player, def, state, coord.x, coord.y, coord.z
|
||||
blocksController.placeBlock(
|
||||
&player, def, state, coord.x, coord.y, coord.z
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -479,23 +484,23 @@ void PlayerController::processRightClick(const Block& def, const Block& target)
|
||||
void PlayerController::updateEntityInteraction(
|
||||
entityid_t eid, bool lclick, bool rclick
|
||||
) {
|
||||
auto entityOpt = level->entities->get(eid);
|
||||
auto entityOpt = level.entities->get(eid);
|
||||
if (!entityOpt.has_value()) {
|
||||
return;
|
||||
}
|
||||
auto entity = *entityOpt;
|
||||
if (lclick) {
|
||||
scripting::on_attacked(entity, player, player->getEntity());
|
||||
scripting::on_attacked(entity, &player, player.getEntity());
|
||||
}
|
||||
if (rclick) {
|
||||
scripting::on_entity_used(entity, player);
|
||||
scripting::on_entity_used(entity, &player);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerController::updateInteraction(float delta) {
|
||||
auto indices = level->content->getIndices();
|
||||
auto chunks = player->chunks.get();
|
||||
const auto& selection = player->selection;
|
||||
auto indices = level.content->getIndices();
|
||||
auto chunks = player.chunks.get();
|
||||
const auto& selection = player.selection;
|
||||
|
||||
if (interactionTimer > 0.0f) {
|
||||
interactionTimer -= delta;
|
||||
@ -512,14 +517,14 @@ void PlayerController::updateInteraction(float delta) {
|
||||
interactionTimer = INTERACTION_RELOAD;
|
||||
}
|
||||
|
||||
auto inventory = player->getInventory();
|
||||
const ItemStack& stack = inventory->getSlot(player->getChosenSlot());
|
||||
auto inventory = player.getInventory();
|
||||
const ItemStack& stack = inventory->getSlot(player.getChosenSlot());
|
||||
auto& item = indices->items.require(stack.getItemId());
|
||||
|
||||
auto vox = updateSelection(maxDistance);
|
||||
if (vox == nullptr) {
|
||||
if (rclick && item.rt.funcsset.on_use) {
|
||||
scripting::on_item_use(player, item);
|
||||
scripting::on_item_use(&player, item);
|
||||
}
|
||||
if (selection.entity) {
|
||||
updateEntityInteraction(selection.entity, lattack, rclick);
|
||||
@ -530,16 +535,16 @@ void PlayerController::updateInteraction(float delta) {
|
||||
auto iend = selection.position;
|
||||
if (lclick && !input.shift && item.rt.funcsset.on_block_break_by) {
|
||||
if (scripting::on_item_break_block(
|
||||
player, item, iend.x, iend.y, iend.z
|
||||
&player, item, iend.x, iend.y, iend.z
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto& target = indices->blocks.require(vox->id);
|
||||
if (lclick) {
|
||||
if (player->isInstantDestruction() && target.breakable) {
|
||||
blocksController->breakBlock(
|
||||
player, target, iend.x, iend.y, iend.z
|
||||
if (player.isInstantDestruction() && target.breakable) {
|
||||
blocksController.breakBlock(
|
||||
&player, target, iend.x, iend.y, iend.z
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -547,10 +552,10 @@ void PlayerController::updateInteraction(float delta) {
|
||||
bool preventDefault = false;
|
||||
if (item.rt.funcsset.on_use_on_block) {
|
||||
preventDefault = scripting::on_item_use_on_block(
|
||||
player, item, iend, selection.normal
|
||||
&player, item, iend, selection.normal
|
||||
);
|
||||
} else if (item.rt.funcsset.on_use) {
|
||||
preventDefault = scripting::on_item_use(player, item);
|
||||
preventDefault = scripting::on_item_use(&player, item);
|
||||
}
|
||||
if (preventDefault) {
|
||||
return;
|
||||
@ -562,10 +567,10 @@ void PlayerController::updateInteraction(float delta) {
|
||||
}
|
||||
if (Events::jactive(BIND_PLAYER_PICK)) {
|
||||
auto coord = selection.actualPosition;
|
||||
pick_block(indices, chunks, player, coord.x, coord.y, coord.z);
|
||||
pick_block(indices, target, player, coord.x, coord.y, coord.z);
|
||||
}
|
||||
}
|
||||
|
||||
Player* PlayerController::getPlayer() {
|
||||
return player;
|
||||
return &player;
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ struct CameraSettings;
|
||||
struct EngineSettings;
|
||||
|
||||
class CameraControl {
|
||||
Player* player;
|
||||
Player& player;
|
||||
std::shared_ptr<Camera> camera;
|
||||
const CameraSettings& settings;
|
||||
glm::vec3 offset;
|
||||
@ -39,21 +39,19 @@ class CameraControl {
|
||||
/// @brief Switch active player camera
|
||||
void switchCamera();
|
||||
public:
|
||||
CameraControl(
|
||||
Player* player, const CameraSettings& settings
|
||||
);
|
||||
CameraControl(Player& player, const CameraSettings& settings);
|
||||
void updateMouse(PlayerInput& input);
|
||||
void update(PlayerInput input, float delta, Chunks* chunks);
|
||||
void update(PlayerInput input, float delta, Chunks& chunks);
|
||||
void refresh();
|
||||
};
|
||||
|
||||
class PlayerController {
|
||||
const EngineSettings& settings;
|
||||
Level* level;
|
||||
Player* player;
|
||||
Level& level;
|
||||
Player& player;
|
||||
PlayerInput input {};
|
||||
CameraControl camControl;
|
||||
BlocksController* blocksController;
|
||||
BlocksController& blocksController;
|
||||
float interactionTimer = 0.0f;
|
||||
|
||||
void updateKeyboard();
|
||||
@ -71,9 +69,9 @@ class PlayerController {
|
||||
public:
|
||||
PlayerController(
|
||||
const EngineSettings& settings,
|
||||
Level* level,
|
||||
Player* player,
|
||||
BlocksController* blocksController
|
||||
Level& level,
|
||||
Player& player,
|
||||
BlocksController& blocksController
|
||||
);
|
||||
|
||||
/// @brief Called after blocks update if not paused
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user