implement player ticks in headless mode & prevent on_player_tick call if player chunk does not exists
This commit is contained in:
parent
8e7dfe3e0b
commit
1cd85b6f77
@ -19,14 +19,13 @@
|
||||
#include "objects/Player.hpp"
|
||||
#include "objects/Players.hpp"
|
||||
|
||||
BlocksController::BlocksController(const Level& level, Lighting* lighting, uint padding)
|
||||
BlocksController::BlocksController(const Level& level, Lighting* lighting)
|
||||
: level(level),
|
||||
chunks(*level.chunks),
|
||||
lighting(lighting),
|
||||
randTickClock(20, 3),
|
||||
blocksTickClock(20, 1),
|
||||
worldTickClock(20, 1),
|
||||
padding(padding) {
|
||||
worldTickClock(20, 1) {
|
||||
}
|
||||
|
||||
void BlocksController::updateSides(int x, int y, int z) {
|
||||
@ -120,9 +119,9 @@ void BlocksController::updateBlock(int x, int y, int z) {
|
||||
}
|
||||
}
|
||||
|
||||
void BlocksController::update(float delta) {
|
||||
void BlocksController::update(float delta, uint padding) {
|
||||
if (randTickClock.update(delta)) {
|
||||
randomTick(randTickClock.getPart(), randTickClock.getParts());
|
||||
randomTick(randTickClock.getPart(), randTickClock.getParts(), padding);
|
||||
}
|
||||
if (blocksTickClock.update(delta)) {
|
||||
onBlocksTick(blocksTickClock.getPart(), blocksTickClock.getParts());
|
||||
@ -169,7 +168,7 @@ void BlocksController::randomTick(
|
||||
}
|
||||
}
|
||||
|
||||
void BlocksController::randomTick(int tickid, int parts) {
|
||||
void BlocksController::randomTick(int tickid, int parts, uint padding) {
|
||||
auto indices = level.content->getIndices();
|
||||
|
||||
std::set<uint64_t> chunksIterated;
|
||||
|
||||
@ -31,11 +31,10 @@ class BlocksController {
|
||||
util::Clock randTickClock;
|
||||
util::Clock blocksTickClock;
|
||||
util::Clock worldTickClock;
|
||||
uint padding;
|
||||
FastRandom random {};
|
||||
std::vector<on_block_interaction> blockInteractionCallbacks;
|
||||
public:
|
||||
BlocksController(const Level& level, Lighting* lighting, uint padding);
|
||||
BlocksController(const Level& level, Lighting* lighting);
|
||||
|
||||
void updateSides(int x, int y, int z);
|
||||
void updateSides(int x, int y, int z, int w, int h, int d);
|
||||
@ -46,11 +45,11 @@ public:
|
||||
Player* player, const Block& def, blockstate state, int x, int y, int z
|
||||
);
|
||||
|
||||
void update(float delta);
|
||||
void update(float delta, uint padding);
|
||||
void randomTick(
|
||||
const Chunk& chunk, int segments, const ContentIndices* indices
|
||||
);
|
||||
void randomTick(int tickid, int parts);
|
||||
void randomTick(int tickid, int parts, uint padding);
|
||||
void onBlocksTick(int tickid, int parts);
|
||||
int64_t createBlockInventory(int x, int y, int z);
|
||||
void bindInventory(int64_t invid, int x, int y, int z);
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
#include "ChunksController.hpp"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
#include "content/Content.hpp"
|
||||
@ -23,9 +21,8 @@
|
||||
const uint MAX_WORK_PER_FRAME = 128;
|
||||
const uint MIN_SURROUNDING = 9;
|
||||
|
||||
ChunksController::ChunksController(Level& level, uint padding)
|
||||
ChunksController::ChunksController(Level& level)
|
||||
: level(level),
|
||||
padding(padding),
|
||||
generator(std::make_unique<WorldGenerator>(
|
||||
level.content->generators.require(level.getWorld()->getGenerator()),
|
||||
level.content,
|
||||
@ -35,7 +32,7 @@ ChunksController::ChunksController(Level& level, uint padding)
|
||||
ChunksController::~ChunksController() = default;
|
||||
|
||||
void ChunksController::update(
|
||||
int64_t maxDuration, int loadDistance, Player& player
|
||||
int64_t maxDuration, int loadDistance, uint padding, Player& player
|
||||
) const {
|
||||
const auto& position = player.getPosition();
|
||||
int centerX = floordiv<CHUNK_W>(position.x);
|
||||
@ -47,7 +44,7 @@ void ChunksController::update(
|
||||
|
||||
for (uint i = 0; i < MAX_WORK_PER_FRAME; i++) {
|
||||
timeutil::Timer timer;
|
||||
if (loadVisible(player)) {
|
||||
if (loadVisible(player, padding)) {
|
||||
int64_t mcs = timer.stop();
|
||||
if (mcstotal + mcs < maxDuration * 1000) {
|
||||
mcstotal += mcs;
|
||||
@ -58,7 +55,7 @@ void ChunksController::update(
|
||||
}
|
||||
}
|
||||
|
||||
bool ChunksController::loadVisible(const Player& player) const {
|
||||
bool ChunksController::loadVisible(const Player& player, uint padding) const {
|
||||
const auto& chunks = *player.chunks;
|
||||
int sizeX = chunks.getWidth();
|
||||
int sizeY = chunks.getHeight();
|
||||
|
||||
@ -15,21 +15,22 @@ class WorldGenerator;
|
||||
class ChunksController {
|
||||
private:
|
||||
Level& level;
|
||||
uint padding;
|
||||
std::unique_ptr<WorldGenerator> generator;
|
||||
|
||||
/// @brief Process one chunk: load it or calculate lights for it
|
||||
bool loadVisible(const Player& player) const;
|
||||
bool loadVisible(const Player& player, uint padding) const;
|
||||
bool buildLights(const Player& player, const std::shared_ptr<Chunk>& chunk) const;
|
||||
void createChunk(const Player& player, int x, int y) const;
|
||||
public:
|
||||
std::unique_ptr<Lighting> lighting;
|
||||
|
||||
ChunksController(Level& level, uint padding);
|
||||
ChunksController(Level& level);
|
||||
~ChunksController();
|
||||
|
||||
/// @param maxDuration milliseconds reserved for chunks loading
|
||||
void update(int64_t maxDuration, int loadDistance, Player& player) const;
|
||||
void update(
|
||||
int64_t maxDuration, int loadDistance, uint padding, Player& player
|
||||
) const;
|
||||
|
||||
const WorldGenerator* getGenerator() const {
|
||||
return generator.get();
|
||||
|
||||
@ -24,25 +24,41 @@ LevelController::LevelController(
|
||||
)
|
||||
: settings(engine->getSettings()),
|
||||
level(std::move(levelPtr)),
|
||||
chunks(std::make_unique<ChunksController>(
|
||||
*level, settings.chunks.padding.get()
|
||||
)) {
|
||||
|
||||
chunks(std::make_unique<ChunksController>(*level)),
|
||||
playerTickClock(20, 3) {
|
||||
if (clientPlayer) {
|
||||
chunks->lighting = std::make_unique<Lighting>(
|
||||
level->content, clientPlayer->chunks.get()
|
||||
);
|
||||
}
|
||||
blocks = std::make_unique<BlocksController>(
|
||||
*level,
|
||||
chunks ? chunks->lighting.get() : nullptr,
|
||||
settings.chunks.padding.get()
|
||||
*level, chunks ? chunks->lighting.get() : nullptr
|
||||
);
|
||||
scripting::on_world_load(this);
|
||||
|
||||
// TODO: do something to players added later
|
||||
int confirmed;
|
||||
do {
|
||||
confirmed = 0;
|
||||
for (const auto& [_, player] : *level->players) {
|
||||
glm::vec3 position = player->getPosition();
|
||||
player->chunks->configure(
|
||||
std::floor(position.x), std::floor(position.z), 1
|
||||
);
|
||||
chunks->update(16, 1, 0, *player);
|
||||
if (player->chunks->get(
|
||||
std::floor(position.x),
|
||||
std::floor(position.y),
|
||||
std::floor(position.z)
|
||||
)) {
|
||||
confirmed++;
|
||||
}
|
||||
}
|
||||
} while (confirmed < level->players->size());
|
||||
}
|
||||
|
||||
void LevelController::update(float delta, bool pause) {
|
||||
for (const auto& [uid, player] : *level->players) {
|
||||
for (const auto& [_, player] : *level->players) {
|
||||
glm::vec3 position = player->getPosition();
|
||||
player->chunks->configure(
|
||||
position.x,
|
||||
@ -52,14 +68,33 @@ void LevelController::update(float delta, bool pause) {
|
||||
chunks->update(
|
||||
settings.chunks.loadSpeed.get(),
|
||||
settings.chunks.loadDistance.get(),
|
||||
settings.chunks.padding.get(),
|
||||
*player
|
||||
);
|
||||
}
|
||||
if (!pause) {
|
||||
// update all objects that needed
|
||||
blocks->update(delta);
|
||||
blocks->update(delta, settings.chunks.padding.get());
|
||||
level->entities->updatePhysics(delta);
|
||||
level->entities->update(delta);
|
||||
for (const auto& [_, player] : *level->players) {
|
||||
if (playerTickClock.update(delta)) {
|
||||
if (player->getId() % playerTickClock.getParts() ==
|
||||
playerTickClock.getPart()) {
|
||||
|
||||
const auto& position = player->getPosition();
|
||||
if (!player->chunks->get(
|
||||
std::floor(position.x),
|
||||
std::floor(position.y),
|
||||
std::floor(position.z)
|
||||
)){
|
||||
scripting::on_player_tick(
|
||||
player.get(), playerTickClock.getTickRate()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
level->entities->clean();
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
#include "BlocksController.hpp"
|
||||
#include "ChunksController.hpp"
|
||||
#include "util/Clock.hpp"
|
||||
|
||||
class Engine;
|
||||
class Level;
|
||||
@ -17,6 +18,8 @@ class LevelController {
|
||||
// Sub-controllers
|
||||
std::unique_ptr<BlocksController> blocks;
|
||||
std::unique_ptr<ChunksController> chunks;
|
||||
|
||||
util::Clock playerTickClock;
|
||||
public:
|
||||
LevelController(Engine* engine, std::unique_ptr<Level> level, Player* clientPlayer);
|
||||
|
||||
|
||||
@ -202,8 +202,7 @@ PlayerController::PlayerController(
|
||||
level(level),
|
||||
player(player),
|
||||
camControl(player, settings.camera),
|
||||
blocksController(blocksController),
|
||||
playerTickClock(20, 3) {
|
||||
blocksController(blocksController) {
|
||||
}
|
||||
|
||||
void PlayerController::onFootstep(const Hitbox& hitbox) {
|
||||
@ -256,13 +255,6 @@ void PlayerController::update(float delta, bool input) {
|
||||
resetKeyboard();
|
||||
}
|
||||
updatePlayer(delta);
|
||||
|
||||
if (playerTickClock.update(delta)) {
|
||||
if (player->getId() % playerTickClock.getParts() ==
|
||||
playerTickClock.getPart()) {
|
||||
scripting::on_player_tick(player, playerTickClock.getTickRate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerController::postUpdate(float delta, bool input, bool pause) {
|
||||
|
||||
@ -54,9 +54,8 @@ class PlayerController {
|
||||
PlayerInput input {};
|
||||
CameraControl camControl;
|
||||
BlocksController* blocksController;
|
||||
util::Clock playerTickClock;
|
||||
|
||||
float interactionTimer = 0.0f;
|
||||
|
||||
void updateKeyboard();
|
||||
void resetKeyboard();
|
||||
void updatePlayer(float delta);
|
||||
|
||||
@ -36,4 +36,8 @@ public:
|
||||
auto end() const {
|
||||
return players.end();
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return players.size();
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user