169 lines
5.2 KiB
C++
169 lines
5.2 KiB
C++
#include "LocalWorld.h"
|
|
|
|
#include "util/PerfTimer.h"
|
|
#include "util/net/PacketView.h"
|
|
#include "client/graph/Renderer.h"
|
|
#include "world/dim/chunk/Chunk.h"
|
|
#include "inv/LocalInventoryRefs.h"
|
|
#include "world/player/LocalPlayer.h"
|
|
#include "client/stream/WorldInterpolationStream.h"
|
|
|
|
LocalWorld::LocalWorld(SubgamePtr game, ServerConnection& conn, Renderer& renderer, vec<string>& perfSections) :
|
|
World(game),
|
|
renderer(renderer),
|
|
net(conn, *this),
|
|
refs(make_shared<LocalInventoryRefs>(game, net)),
|
|
debug(player.l()->getDebug(), game, *this, perfSections),
|
|
// worldGenStream(make_shared<WorldInterpolationStream>(*game.l(), *this, 55)),
|
|
player(make_shared<LocalPlayer>(game, *this, DimensionPtr(nullptr), renderer)) {
|
|
|
|
// lock = renderer.window.onResize(Util::bind_this(&debugGui, &DebugGui::bufferResized));
|
|
}
|
|
|
|
void LocalWorld::init() {
|
|
net.init(Util::bind_this(&(*refs), &LocalInventoryRefs::packetReceived));
|
|
refs->init();
|
|
}
|
|
|
|
bool LocalWorld::updatePlayerDimension() {
|
|
if (defaultDimension.empty()) return false;
|
|
player->setDim(getDefaultDimension());
|
|
activeDimension = getDefaultDimension().l();
|
|
return true;
|
|
}
|
|
|
|
void LocalWorld::update(f64 delta, vec<usize>& perfTimings, PerfTimer& perf) {
|
|
|
|
// Updates the dimensions.
|
|
perf.start("update:world");
|
|
for (auto& dimension : dimensions) dimension->update(delta);
|
|
|
|
// Update children
|
|
perf.start("update:player");
|
|
if (*player) player.l()->update(delta, renderer.window.input.getMouseDelta());
|
|
refs->update(delta, net);
|
|
|
|
// Update the network
|
|
perf.resume("other");
|
|
net.update();
|
|
|
|
// Update debug interface
|
|
perf.start("update:debug");
|
|
debug.update(
|
|
player.l(), delta,
|
|
lastInterpolations, net.serverSideChunkGens, net.recvPackets,
|
|
perfTimings,
|
|
activeDimension->getMeshChunksDrawn(),
|
|
activeDimension->getMeshChunksCommitted());
|
|
perf.resume("other");
|
|
|
|
// Toggle regular interface
|
|
// if (renderer.window.input.keyPressed(GLFW_KEY_F1)) {
|
|
// hudVisible = !hudVisible;
|
|
// player.l()->setHudVisible(hudVisible);
|
|
// debugGui.changeVisibility(hudVisible ? debugVisible ? DebugGui::Visibility::ON :
|
|
// DebugGui::Visibility::FPS_ONLY : DebugGui::Visibility::OFF);
|
|
// }
|
|
//
|
|
// // Toggle debug interface
|
|
// if (renderer.window.input.keyPressed(GLFW_KEY_F3)) {
|
|
// debugVisible = !debugVisible;
|
|
// debugGui.changeVisibility(hudVisible ? debugVisible ? DebugGui::Visibility::ON :
|
|
// DebugGui::Visibility::FPS_ONLY : DebugGui::Visibility::OFF);
|
|
// }
|
|
}
|
|
|
|
void LocalWorld::handleWorldPacket(uptr<PacketView> p) {
|
|
if (p->type == Packet::Type::CHUNK)
|
|
commitChunk(make_shared<Chunk>(p->d.data));
|
|
else if (p->type == Packet::Type::MAPBLOCK)
|
|
while (!p->d.atEnd())
|
|
commitChunk(make_shared<Chunk>(p->d.read<string>()));
|
|
}
|
|
|
|
void LocalWorld::handlePlayerEntPacket(uptr<PacketView> p) {
|
|
if (!player) throw std::runtime_error("Received playerEnt info *before* the player was created.");
|
|
|
|
u32 id = p->d.read<u32>();
|
|
if (player->getId() == id) return;
|
|
|
|
bool found = false;
|
|
for (auto& entity : getActiveDimension().l()->playerEntities) {
|
|
if (entity.getId() == id) {
|
|
entity.interpPos(p->d.read<vec3>());
|
|
entity.interpRotateZ(-p->d.read<f32>() + 90);
|
|
entity.interpRotateY(-p->d.read<f32>() + 90);
|
|
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (found) return;
|
|
|
|
//TODO: Reimplement player models.
|
|
// auto playerModel = std::make_shared<Model>();
|
|
// playerModel->fromSerialized(static_cast<LocalSubgame&>(game).models.models["zeus:default:player"],
|
|
// { static_cast<LocalSubgame&>(game).textures["zeus:default:player"] });
|
|
// getActiveDimension().playerEntities.emplace_back(p->d.read<glm::vec3>(), id, playerModel);
|
|
}
|
|
|
|
void LocalWorld::handleModMessage(const string& channel, const string& message) {
|
|
game->getParser().safe_function(game->getParser().core["trigger"], "message",
|
|
channel, game->getParser().safe_function(game->getParser().core["deserialize"], message));
|
|
}
|
|
|
|
void LocalWorld::commitChunk(sptr<Chunk> c) {
|
|
activeDimension->setChunk(std::move(c));
|
|
}
|
|
|
|
DimensionPtr LocalWorld::createDimension(const string& identifier, std::unordered_set<string>& biomes) {
|
|
auto mapGen = std::make_shared<MapGen>(**game, *this, 0 /* TODO: Get the seed here */, biomes);
|
|
dimensions.emplace_back(std::make_shared<LocalDimension>(
|
|
game, *this, identifier, this->dimensions.size(), std::move(mapGen)));
|
|
|
|
dimensionIndexes[identifier] = dimensions.size() - 1;
|
|
DimensionPtr d = dimensions.back();
|
|
return d;
|
|
}
|
|
|
|
void LocalWorld::sendMessage(const string& channel, const string& message) {
|
|
net.sendPacket(Serializer().append(channel).append(message)
|
|
.packet(Packet::Type::MOD_MESSAGE), Packet::Channel::INTERACT);
|
|
}
|
|
|
|
DimensionPtr LocalWorld::getActiveDimension() {
|
|
return activeDimension;
|
|
}
|
|
|
|
void LocalWorld::setActiveDimension(DimensionPtr dim) {
|
|
activeDimension->deactivate();
|
|
activeDimension = dim.l();
|
|
}
|
|
|
|
ClientNetworkInterpreter& LocalWorld::getNet() {
|
|
return net;
|
|
}
|
|
|
|
PlayerPtr LocalWorld::getPlayer() {
|
|
return player;
|
|
}
|
|
|
|
InventoryRefsPtr LocalWorld::getRefs() {
|
|
return refs;
|
|
}
|
|
|
|
void LocalWorld::drawChunks() {
|
|
activeDimension->renderChunks(renderer);
|
|
}
|
|
|
|
void LocalWorld::drawEntities() {
|
|
activeDimension->renderEntities(renderer);
|
|
player.l()->draw(renderer);
|
|
}
|
|
|
|
void LocalWorld::drawInterface() {
|
|
player.l()->drawHud(renderer);
|
|
// debugGui.draw(renderer);
|
|
player.l()->drawMenu(renderer);
|
|
}
|