From d899b21504c02cae99eb3688e561cf9bad4120c4 Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Mon, 27 Jul 2020 09:05:53 +0500 Subject: Support for non-overworld dimensions --- cwd/assets/altcraft/scripts/blocks.lua | 6 +++--- cwd/assets/altcraft/scripts/init.lua | 4 ++++ src/GameState.cpp | 17 ++++++++++++++++- src/Network.cpp | 2 +- src/Packet.hpp | 24 +++++++++++++++++++++++- src/Plugin.cpp | 11 +++++++++++ src/Section.cpp | 5 ++++- src/World.cpp | 20 ++++++++++++++++++-- src/World.hpp | 11 +++++++++++ 9 files changed, 91 insertions(+), 9 deletions(-) diff --git a/cwd/assets/altcraft/scripts/blocks.lua b/cwd/assets/altcraft/scripts/blocks.lua index 325a8fc..5678677 100644 --- a/cwd/assets/altcraft/scripts/blocks.lua +++ b/cwd/assets/altcraft/scripts/blocks.lua @@ -301,9 +301,9 @@ local function RegisterBlocks() AC.RegisterBlock(BlockId.new(89,0), true, "glowstone", "normal") - AC.RegisterBlock(BlockId.new(90,0), true, "portal", "axis=z") - AC.RegisterBlock(BlockId.new(90,1), true, "portal", "axis=x") - AC.RegisterBlock(BlockId.new(90,2), true, "portal", "axis=z") + AC.RegisterBlock(BlockId.new(90,0), false, "portal", "axis=z") + AC.RegisterBlock(BlockId.new(90,1), false, "portal", "axis=x") + AC.RegisterBlock(BlockId.new(90,2), false, "portal", "axis=z") AC.RegisterBlock(BlockId.new(93,0), true, "unpowered_repeater", "delay=1,facing=east,locked=false") AC.RegisterBlock(BlockId.new(93,1), true, "unpowered_repeater", "delay=1,facing=south,locked=false") diff --git a/cwd/assets/altcraft/scripts/init.lua b/cwd/assets/altcraft/scripts/init.lua index 5021a00..96b5ec3 100644 --- a/cwd/assets/altcraft/scripts/init.lua +++ b/cwd/assets/altcraft/scripts/init.lua @@ -40,5 +40,9 @@ function plugin.onRequestBlockInfo(blockPos) return blocks.GetBlockInfo(blockPos) end +AC.RegisterDimension(0, Dimension.new("overworld", true)) +AC.RegisterDimension(-1, Dimension.new("the_nether", false)) +AC.RegisterDimension(1, Dimension.new("the_end", false)) + AC.RegisterPlugin(plugin) plugin = nil \ No newline at end of file diff --git a/src/GameState.cpp b/src/GameState.cpp index e4278ec..8e50ee6 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -254,6 +254,7 @@ void GameState::UpdatePacket(std::shared_ptr ptr) { entity.entityId = packet->EntityId; entity.width = 0.6; entity.height = 1.8; + world = World(packet->Dimension); world.AddEntity(entity); player = world.GetEntityPtr(entity.entityId); @@ -385,8 +386,22 @@ void GameState::UpdatePacket(std::shared_ptr ptr) { break; case ResourcePackSend: break; - case Respawn: + case Respawn: { + auto packet = std::static_pointer_cast(ptr); + Entity entity; + entity.entityId = player->entityId; + entity.width = 0.6; + entity.height = 1.8; + world = World(packet->Dimension); + world.AddEntity(entity); + player = world.GetEntityPtr(entity.entityId); + + gameStatus.gamemode = (packet->Gamemode & 0b11111011); + gameStatus.dimension = packet->Dimension; + gameStatus.difficulty = packet->Difficulty; + gameStatus.levelType = packet->LevelType; break; + } case EntityHeadLook: break; case SelectAdvancementTab: diff --git a/src/Network.cpp b/src/Network.cpp index 431a5b1..bb92e7f 100644 --- a/src/Network.cpp +++ b/src/Network.cpp @@ -240,7 +240,7 @@ std::shared_ptr Network::ParsePacketPlay(PacketNamePlayCB id) { case ResourcePackSend: break; case Respawn: - break; + return std::make_shared(); case EntityHeadLook: break; case WorldBorder: diff --git a/src/Packet.hpp b/src/Packet.hpp index 7b18ce1..275de75 100644 --- a/src/Packet.hpp +++ b/src/Packet.hpp @@ -1146,4 +1146,26 @@ struct PacketPlayerBlockPlacement : Packet { float cursorPositionX; float cursorPositionY; float cursorPositionZ; -}; \ No newline at end of file +}; + +struct PacketRespawn : Packet { + void ToStream(StreamOutput* stream) override { + + } + + void FromStream(StreamInput* stream) override { + Dimension = stream->ReadInt(); + Difficulty = stream->ReadUByte(); + Gamemode = stream->ReadUByte(); + LevelType = stream->ReadString(); + } + + int GetPacketId() override { + return PacketNamePlayCB::Respawn; + } + + int Dimension; + unsigned char Difficulty; + unsigned char Gamemode; + std::string LevelType; +}; diff --git a/src/Plugin.cpp b/src/Plugin.cpp index 8d2de94..618ea9d 100644 --- a/src/Plugin.cpp +++ b/src/Plugin.cpp @@ -70,6 +70,10 @@ namespace PluginApi { variant }); } + + void RegisterDimension(int dimId, Dimension dim) { + RegisterNewDimension(dimId, dim); + } } int LoadFileRequire(lua_State* L) { @@ -193,6 +197,12 @@ void PluginSystem::Init() { "blockstate", &BlockInfo::blockstate, "variant", &BlockInfo::variant); + lua.new_usertype("Dimension", + "new", sol::factories([]() {return Dimension{ 0,0 }; }, + [](std::string dimName, bool skylight) {return Dimension{ dimName, skylight }; }), + "name", &Dimension::name, + "skylight", &Dimension::skylight); + sol::table apiTable = lua["AC"].get_or_create(); apiTable["RegisterPlugin"] = PluginApi::RegisterPlugin; @@ -201,6 +211,7 @@ void PluginSystem::Init() { apiTable["LogError"] = PluginApi::LogError; apiTable["GetGameState"] = PluginApi::GetGameState; apiTable["RegisterBlock"] = PluginApi::RegisterBlock; + apiTable["RegisterDimension"] = PluginApi::RegisterDimension; } void PluginSystem::Execute(const std::string &luaCode, bool except) { diff --git a/src/Section.cpp b/src/Section.cpp index 29a6a0e..4a15c58 100644 --- a/src/Section.cpp +++ b/src/Section.cpp @@ -42,7 +42,10 @@ Section::Section(Vector pos, unsigned char bitsPerBlock, std::vectorblock = std::move(blockData); this->palette = std::move(palette); std::copy(lightData.begin(), lightData.end(), light); - std::copy(skyData.begin(), skyData.end(), sky); + if (!skyData.empty()) + std::copy(skyData.begin(), skyData.end(), sky); + else + memset(sky, 0, sizeof(sky)); hash = -1; CalculateHash(); diff --git a/src/World.cpp b/src/World.cpp index 00a1a19..d767871 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -9,6 +9,16 @@ #include "Packet.hpp" #include "Collision.hpp" +std::map registeredDimensions; + +void RegisterNewDimension(int dimensionId, Dimension newDimension) { + registeredDimensions[dimensionId] = newDimension; +} + +World::World(int dimensionId) : dimension(dimensionId) { + +} + void World::ParseChunkData(std::shared_ptr packet) { StreamBuffer chunkData(packet->Data.data(), packet->Data.size()); std::bitset<16> bitmask(packet->PrimaryBitMask); @@ -24,7 +34,13 @@ void World::ParseChunkData(std::shared_ptr packet) { UpdateSectionsList(); } else { - std::swap(sections.at(chunkPosition), section); + auto it = sections.find(chunkPosition); + if (it == sections.end()) { + LOG(WARNING) << "Chunk updating empty chunk"; + sections.insert(std::make_pair(chunkPosition, section)); + } + else + std::swap(sections.at(chunkPosition), section); } PUSH_EVENT("ChunkChanged", chunkPosition); @@ -44,7 +60,7 @@ Section World::ParseSection(StreamInput *data, Vector position) { auto dataArray = data->ReadByteArray(dataArrayLength * 8); auto blockLight = data->ReadByteArray(2048); std::vector skyLight; - if (dimension == 0) + if (registeredDimensions[dimension].skylight) skyLight = data->ReadByteArray(2048); long long *blockData = reinterpret_cast(dataArray.data()); diff --git a/src/World.hpp b/src/World.hpp index 6c9a615..3e53efc 100644 --- a/src/World.hpp +++ b/src/World.hpp @@ -25,6 +25,13 @@ struct RaycastResult { VectorF hitPos; }; +struct Dimension { + std::string name; + bool skylight; +}; + +void RegisterNewDimension(int dimensionId, Dimension newDimension); + class World { int dimension = 0; @@ -40,6 +47,10 @@ class World { public: + World() = default; + + World(int dimensionId); + void ParseChunkData(std::shared_ptr packet); void ParseChunkData(std::shared_ptr packet); -- cgit v1.2.3