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