introduce local player
This commit is contained in:
parent
b5999fe364
commit
65fec4f4a9
@ -272,7 +272,7 @@ PacksManager Engine::createPacksManager(const fs::path& worldFolder) {
|
||||
return manager;
|
||||
}
|
||||
|
||||
void Engine::setLevelConsumer(consumer<std::unique_ptr<Level>> levelConsumer) {
|
||||
void Engine::setLevelConsumer(OnWorldOpen levelConsumer) {
|
||||
this->levelConsumer = std::move(levelConsumer);
|
||||
}
|
||||
|
||||
@ -446,14 +446,14 @@ void Engine::setLanguage(std::string locale) {
|
||||
langs::setup(paths.getResourcesFolder(), std::move(locale), contentPacks);
|
||||
}
|
||||
|
||||
void Engine::onWorldOpen(std::unique_ptr<Level> level) {
|
||||
void Engine::onWorldOpen(std::unique_ptr<Level> level, int64_t localPlayer) {
|
||||
logger.info() << "world open";
|
||||
levelConsumer(std::move(level));
|
||||
levelConsumer(std::move(level), localPlayer);
|
||||
}
|
||||
|
||||
void Engine::onWorldClosed() {
|
||||
logger.info() << "world closed";
|
||||
levelConsumer(nullptr);
|
||||
levelConsumer(nullptr, -1);
|
||||
}
|
||||
|
||||
void Engine::quit() {
|
||||
|
||||
@ -53,6 +53,8 @@ struct CoreParameters {
|
||||
std::filesystem::path scriptFile;
|
||||
};
|
||||
|
||||
using OnWorldOpen = std::function<void(std::unique_ptr<Level>, int64_t)>;
|
||||
|
||||
class Engine : public util::ObjectsKeeper {
|
||||
CoreParameters params;
|
||||
EngineSettings settings;
|
||||
@ -71,7 +73,7 @@ class Engine : public util::ObjectsKeeper {
|
||||
std::unique_ptr<gui::GUI> gui;
|
||||
PostRunnables postRunnables;
|
||||
Time time;
|
||||
consumer<std::unique_ptr<Level>> levelConsumer;
|
||||
OnWorldOpen levelConsumer;
|
||||
bool quitSignal = false;
|
||||
|
||||
void loadControls();
|
||||
@ -134,7 +136,7 @@ public:
|
||||
/// @brief Get engine resource paths controller
|
||||
ResPaths* getResPaths();
|
||||
|
||||
void onWorldOpen(std::unique_ptr<Level> level);
|
||||
void onWorldOpen(std::unique_ptr<Level> level, int64_t localPlayer);
|
||||
void onWorldClosed();
|
||||
|
||||
void quit();
|
||||
@ -166,7 +168,7 @@ public:
|
||||
|
||||
PacksManager createPacksManager(const fs::path& worldFolder);
|
||||
|
||||
void setLevelConsumer(consumer<std::unique_ptr<Level>> levelConsumer);
|
||||
void setLevelConsumer(OnWorldOpen levelConsumer);
|
||||
|
||||
SettingsHandler& getSettingsHandler();
|
||||
|
||||
|
||||
@ -15,14 +15,16 @@ Mainloop::Mainloop(Engine& engine) : engine(engine) {
|
||||
void Mainloop::run() {
|
||||
auto& time = engine.getTime();
|
||||
|
||||
engine.setLevelConsumer([this](auto level) {
|
||||
engine.setLevelConsumer([this](auto level, int64_t localPlayer) {
|
||||
if (level == nullptr) {
|
||||
// destroy LevelScreen and run quit callbacks
|
||||
engine.setScreen(nullptr);
|
||||
// create and go to menu screen
|
||||
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
||||
} else {
|
||||
engine.setScreen(std::make_shared<LevelScreen>(engine, std::move(level)));
|
||||
engine.setScreen(std::make_shared<LevelScreen>(
|
||||
engine, std::move(level), localPlayer
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ void ServerMainloop::run() {
|
||||
logger.info() << "nothing to do";
|
||||
return;
|
||||
}
|
||||
engine.setLevelConsumer([this](auto level) {
|
||||
engine.setLevelConsumer([this](auto level, auto) {
|
||||
setLevel(std::move(level));
|
||||
});
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include "graphics/render/ChunksRenderer.hpp"
|
||||
#include "logic/scripting/scripting.hpp"
|
||||
#include "objects/Player.hpp"
|
||||
#include "objects/Players.hpp"
|
||||
#include "objects/Entities.hpp"
|
||||
#include "objects/EntityDef.hpp"
|
||||
#include "physics/Hitbox.hpp"
|
||||
@ -41,6 +42,7 @@ static std::shared_ptr<Label> create_label(wstringsupplier supplier) {
|
||||
|
||||
// TODO: move to xml
|
||||
// TODO: move to xml finally
|
||||
// TODO: move to xml finally
|
||||
std::shared_ptr<UINode> create_debug_panel(
|
||||
Engine& engine,
|
||||
Level& level,
|
||||
@ -103,6 +105,10 @@ std::shared_ptr<UINode> create_debug_panel(
|
||||
return L"entities: "+std::to_wstring(level.entities->size())+L" next: "+
|
||||
std::to_wstring(level.entities->peekNextID());
|
||||
}));
|
||||
panel->add(create_label([&]() {
|
||||
return L"players: "+std::to_wstring(level.players->size())+L" local: "+
|
||||
std::to_wstring(player.getId());
|
||||
}));
|
||||
panel->add(create_label([&]() -> std::wstring {
|
||||
const auto& vox = player.selection.vox;
|
||||
std::wstringstream stream;
|
||||
|
||||
@ -36,9 +36,10 @@
|
||||
|
||||
static debug::Logger logger("level-screen");
|
||||
|
||||
LevelScreen::LevelScreen(Engine& engine, std::unique_ptr<Level> levelPtr)
|
||||
: Screen(engine), postProcessing(std::make_unique<PostProcessing>())
|
||||
{
|
||||
LevelScreen::LevelScreen(
|
||||
Engine& engine, std::unique_ptr<Level> levelPtr, int64_t localPlayer
|
||||
)
|
||||
: Screen(engine), postProcessing(std::make_unique<PostProcessing>()) {
|
||||
Level* level = levelPtr.get();
|
||||
|
||||
auto& settings = engine.getSettings();
|
||||
@ -46,7 +47,9 @@ LevelScreen::LevelScreen(Engine& engine, std::unique_ptr<Level> levelPtr)
|
||||
auto menu = engine.getGUI()->getMenu();
|
||||
menu->reset();
|
||||
|
||||
auto player = level->players->get(0);
|
||||
auto player = level->players->get(localPlayer);
|
||||
assert(player != nullptr);
|
||||
|
||||
controller =
|
||||
std::make_unique<LevelController>(&engine, std::move(levelPtr), player);
|
||||
playerController = std::make_unique<PlayerController>(
|
||||
@ -173,6 +176,7 @@ void LevelScreen::update(float delta) {
|
||||
updateHotkeys();
|
||||
}
|
||||
|
||||
auto level = controller->getLevel();
|
||||
auto player = playerController->getPlayer();
|
||||
auto camera = player->currentCamera;
|
||||
|
||||
@ -189,7 +193,6 @@ void LevelScreen::update(float delta) {
|
||||
camera->dir,
|
||||
glm::vec3(0, 1, 0)
|
||||
);
|
||||
auto level = controller->getLevel();
|
||||
const auto& settings = engine.getSettings();
|
||||
|
||||
if (!hud->isPause()) {
|
||||
|
||||
@ -34,7 +34,9 @@ class LevelScreen : public Screen {
|
||||
void initializeContent();
|
||||
void initializePack(ContentPackRuntime* pack);
|
||||
public:
|
||||
LevelScreen(Engine& engine, std::unique_ptr<Level> level);
|
||||
LevelScreen(
|
||||
Engine& engine, std::unique_ptr<Level> level, int64_t localPlayer
|
||||
);
|
||||
~LevelScreen();
|
||||
|
||||
void update(float delta) override;
|
||||
|
||||
@ -92,7 +92,7 @@ bool ChunksController::loadVisible(const Player& player, uint padding) const {
|
||||
}
|
||||
|
||||
const auto& chunk = chunks.getChunks()[nearZ * sizeX + nearX];
|
||||
if (chunk != nullptr || !assigned) {
|
||||
if (chunk != nullptr || !assigned || !player.isLoadingChunks()) {
|
||||
return false;
|
||||
}
|
||||
int offsetX = chunks.getOffsetX();
|
||||
@ -101,7 +101,9 @@ bool ChunksController::loadVisible(const Player& player, uint padding) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChunksController::buildLights(const Player& player, const std::shared_ptr<Chunk>& chunk) const {
|
||||
bool ChunksController::buildLights(
|
||||
const Player& player, const std::shared_ptr<Chunk>& chunk
|
||||
) const {
|
||||
int surrounding = 0;
|
||||
for (int oz = -1; oz <= 1; oz++) {
|
||||
for (int ox = -1; ox <= 1; ox++) {
|
||||
|
||||
@ -143,7 +143,9 @@ static bool load_world_content(Engine& engine, const fs::path& folder) {
|
||||
}
|
||||
|
||||
static void load_world(
|
||||
Engine& engine, const std::shared_ptr<WorldFiles>& worldFiles
|
||||
Engine& engine,
|
||||
const std::shared_ptr<WorldFiles>& worldFiles,
|
||||
int64_t localPlayer
|
||||
) {
|
||||
try {
|
||||
auto content = engine.getContent();
|
||||
@ -151,7 +153,7 @@ static void load_world(
|
||||
auto& settings = engine.getSettings();
|
||||
|
||||
auto level = World::load(worldFiles, settings, *content, packs);
|
||||
engine.onWorldOpen(std::move(level));
|
||||
engine.onWorldOpen(std::move(level), localPlayer);
|
||||
} catch (const world_load_error& error) {
|
||||
guiutil::alert(
|
||||
engine,
|
||||
@ -233,7 +235,7 @@ void EngineController::openWorld(const std::string& name, bool confirmConvert) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
load_world(engine, std::move(worldFiles));
|
||||
load_world(engine, std::move(worldFiles), localPlayer);
|
||||
}
|
||||
|
||||
inline uint64_t str2seed(const std::string& seedstr) {
|
||||
@ -279,9 +281,13 @@ void EngineController::createWorld(
|
||||
engine.getContentPacks()
|
||||
);
|
||||
if (!engine.isHeadless()) {
|
||||
level->players->create();
|
||||
level->players->create(localPlayer);
|
||||
}
|
||||
engine.onWorldOpen(std::move(level));
|
||||
engine.onWorldOpen(std::move(level), localPlayer);
|
||||
}
|
||||
|
||||
void EngineController::setLocalPlayer(int64_t player) {
|
||||
localPlayer = player;
|
||||
}
|
||||
|
||||
void EngineController::reopenWorld(World* world) {
|
||||
|
||||
@ -12,6 +12,7 @@ class LevelController;
|
||||
class EngineController {
|
||||
Engine& engine;
|
||||
|
||||
int64_t localPlayer = -1;
|
||||
void onMissingContent(const std::shared_ptr<ContentReport>& report);
|
||||
public:
|
||||
EngineController(Engine& engine);
|
||||
@ -37,5 +38,7 @@ public:
|
||||
const std::string& generatorID
|
||||
);
|
||||
|
||||
void setLocalPlayer(int64_t player);
|
||||
|
||||
void reopenWorld(World* world);
|
||||
};
|
||||
|
||||
@ -50,6 +50,10 @@ LevelController::LevelController(
|
||||
do {
|
||||
confirmed = 0;
|
||||
for (const auto& [_, player] : *level->players) {
|
||||
if (!player->isLoadingChunks()) {
|
||||
confirmed++;
|
||||
continue;
|
||||
}
|
||||
glm::vec3 position = player->getPosition();
|
||||
player->chunks->configure(
|
||||
std::floor(position.x), std::floor(position.z), 1
|
||||
@ -69,6 +73,7 @@ void LevelController::update(float delta, bool pause) {
|
||||
if (player->isSuspended()) {
|
||||
continue;
|
||||
}
|
||||
player->updateEntity();
|
||||
glm::vec3 position = player->getPosition();
|
||||
player->chunks->configure(
|
||||
position.x,
|
||||
|
||||
@ -305,7 +305,6 @@ void PlayerController::resetKeyboard() {
|
||||
}
|
||||
|
||||
void PlayerController::updatePlayer(float delta) {
|
||||
player.updateEntity();
|
||||
player.updateInput(input, delta);
|
||||
}
|
||||
|
||||
|
||||
@ -55,10 +55,15 @@ static int l_new_world(lua::State* L) {
|
||||
auto name = lua::require_string(L, 1);
|
||||
auto seed = lua::require_string(L, 2);
|
||||
auto generator = lua::require_string(L, 3);
|
||||
int64_t localPlayer = 0;
|
||||
if (lua::gettop(L) >= 4) {
|
||||
localPlayer = lua::tointeger(L, 4);
|
||||
}
|
||||
if (level != nullptr) {
|
||||
throw std::runtime_error("world must be closed before");
|
||||
}
|
||||
auto controller = engine->getController();
|
||||
controller->setLocalPlayer(localPlayer);
|
||||
controller->createWorld(name, seed, generator);
|
||||
return 0;
|
||||
}
|
||||
@ -71,6 +76,7 @@ static int l_open_world(lua::State* L) {
|
||||
throw std::runtime_error("world must be closed before");
|
||||
}
|
||||
auto controller = engine->getController();
|
||||
controller->setLocalPlayer(0);
|
||||
controller->openWorld(name, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -52,6 +52,7 @@ static int l_set_vel(lua::State* L) {
|
||||
auto x = lua::tonumber(L, 2);
|
||||
auto y = lua::tonumber(L, 3);
|
||||
auto z = lua::tonumber(L, 4);
|
||||
|
||||
if (auto hitbox = player->getHitbox()) {
|
||||
hitbox->velocity = glm::vec3(x, y, z);
|
||||
}
|
||||
@ -272,15 +273,19 @@ static int l_set_name(lua::State* L) {
|
||||
}
|
||||
|
||||
static int l_create(lua::State* L) {
|
||||
auto player = level->players->create();
|
||||
if (lua::isstring(L, 1)) {
|
||||
player->setName(lua::require_string(L, 1));
|
||||
int64_t playerId = Players::NONE;
|
||||
if (lua::gettop(L) >= 2) {
|
||||
playerId = lua::tointeger(L, 2);
|
||||
}
|
||||
auto player = level->players->create(playerId);
|
||||
player->setName(lua::require_string(L, 1));
|
||||
return lua::pushinteger(L, player->getId());
|
||||
}
|
||||
|
||||
static int l_delete(lua::State* L) {
|
||||
level->players->remove(lua::tointeger(L, 1));
|
||||
auto id = lua::tointeger(L, 1);
|
||||
level->players->suspend(id);
|
||||
level->players->remove(id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -20,10 +20,19 @@ Player* Players::get(int64_t id) const {
|
||||
return found->second.get();
|
||||
}
|
||||
|
||||
Player* Players::create() {
|
||||
Player* Players::create(int64_t id) {
|
||||
int64_t& nextPlayerID = level.getWorld()->getInfo().nextPlayerId;
|
||||
if (id == NONE) {
|
||||
id = nextPlayerID++;
|
||||
} else {
|
||||
if (auto player = get(id)) {
|
||||
return player;
|
||||
}
|
||||
nextPlayerID = std::max(id + 1, nextPlayerID);
|
||||
}
|
||||
auto playerPtr = std::make_unique<Player>(
|
||||
level,
|
||||
level.getWorld()->getInfo().nextPlayerId++,
|
||||
id,
|
||||
"",
|
||||
glm::vec3(0, DEF_PLAYER_Y, 0),
|
||||
DEF_PLAYER_SPEED,
|
||||
|
||||
@ -14,6 +14,9 @@ class Level;
|
||||
class Player;
|
||||
|
||||
class Players : public Serializable {
|
||||
public:
|
||||
static inline int64_t NONE = -1;
|
||||
private:
|
||||
Level& level;
|
||||
std::unordered_map<int64_t, std::unique_ptr<Player>> players;
|
||||
|
||||
@ -23,7 +26,7 @@ public:
|
||||
|
||||
Player* get(int64_t id) const;
|
||||
|
||||
Player* create();
|
||||
Player* create(int64_t id=NONE);
|
||||
|
||||
void suspend(int64_t id);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user