From a077065aecc536c1ae2187798761275d29fa8d57 Mon Sep 17 00:00:00 2001 From: Auri Date: Sun, 15 Aug 2021 17:21:12 -0700 Subject: [PATCH] Read description VVV World edit mod, only selects for now. Text Formatting Tweak default font to look good in bold. Fix Server locking up when too many player packets are sent. Added chat mod, which *almost* works. Update world noise. --- assets/base/script/modules/string.lua | 12 + assets/base/script/modules/vector.lua | 15 +- assets/shader/world/entity.fs | 4 +- assets/textures/ui/font.png | Bin 953 -> 1685 bytes assets/textures/ui/font.xcf | Bin 17777 -> 16395 bytes src/client/entity/WireframeEntity.cpp | 166 ++++---- src/client/entity/WireframeEntity.h | 32 +- src/client/graph/Renderer.cpp | 5 + src/client/gui/DebugGui.cpp | 7 +- src/client/gui/basic/GuiInventoryItem.cpp | 2 +- src/client/gui/basic/GuiText.cpp | 354 +++++++++++------- src/client/gui/basic/GuiText.h | 64 ++-- src/client/gui/compound/GuiCellGraph.cpp | 2 +- src/client/gui/compound/GuiLabelledGraph.cpp | 2 +- src/client/gui/compound/GuiPerfGraph.cpp | 5 +- src/client/scene/ConnectScene.cpp | 2 +- src/client/scene/MainMenuScene.cpp | 4 +- src/game/atlas/TextureAtlas.cpp | 20 +- src/lua/usertype/Dimension.cpp | 19 +- src/lua/usertype/Entity.cpp | 17 +- src/lua/usertype/Entity.h | 6 +- src/lua/usertype/LuaGuiElement.cpp | 16 +- src/lua/usertype/LuaGuiElement.h | 5 +- src/lua/usertype/Player.cpp | 6 + src/lua/usertype/Player.h | 147 ++++---- src/server/Server.cpp | 15 +- src/server/stream/ServerGenStream.cpp | 6 +- src/server/stream/ServerGenStream.h | 6 +- src/util/Bounds.cpp | 4 +- src/util/Util.h | 12 +- src/world/ServerWorld.cpp | 112 +++--- src/world/dim/LocalDimension.cpp | 7 + src/world/dim/ServerDimension.h | 2 +- src/world/dim/chunk/Chunk.cpp | 1 - src/world/dim/ent/DrawableEntity.cpp | 1 - src/world/dim/ent/LocalLuaEntity.cpp | 25 +- src/world/dim/ent/LocalLuaEntity.h | 9 + src/world/gen/MapGen.cpp | 3 +- src/world/gen/NoiseSample.cpp | 10 +- src/world/gen/NoiseSample.h | 55 ++- src/world/player/LocalPlayer.cpp | 6 +- src/world/player/LocalPlayer.h | 2 + src/world/player/Player.h | 2 + src/world/player/ServerPlayer.cpp | 6 +- src/world/player/ServerPlayer.h | 2 + subgames/zeus/mods/auri_chat/conf.json | 5 + subgames/zeus/mods/auri_chat/script/api.lua | 8 + .../zeus/mods/auri_chat/script/api_client.lua | 58 +++ .../zeus/mods/auri_chat/script/api_server.lua | 63 ++++ .../mods/auri_chat/script/category_icon.xcf | Bin 0 -> 952 bytes subgames/zeus/mods/auri_chat/script/gui.lua | 102 +++++ subgames/zeus/mods/auri_chat/script/init.lua | 8 + subgames/zeus/mods/auri_chat/script/test.lua | 29 ++ .../mods/auri_chat/textures/chat_icon.png | Bin 0 -> 525 bytes .../mods/auri_chat/textures/commands_icon.png | Bin 0 -> 541 bytes .../mods/auri_chat/textures/debug_icon.png | Bin 0 -> 546 bytes .../zeus/mods/auri_world_edit/script/init.lua | 48 +++ .../mods/auri_world_edit/textures/wand.png | Bin 0 -> 2451 bytes .../zeus/mods/zeus_flowers/textures/pink.png | Bin 0 -> 334 bytes .../zeus_inventory/textures/player_frame.png | Bin 0 -> 7032 bytes .../mods/zeus_world/script/biomes/desert.lua | 203 +++++----- .../mods/zeus_world/script/biomes/plains.lua | 92 +++-- .../zeus_world/script/biomes/world_noise.lua | 31 +- subgames/zeus/mods/zeus_world/script/init.lua | 6 +- 64 files changed, 1201 insertions(+), 650 deletions(-) create mode 100644 subgames/zeus/mods/auri_chat/conf.json create mode 100644 subgames/zeus/mods/auri_chat/script/api.lua create mode 100644 subgames/zeus/mods/auri_chat/script/api_client.lua create mode 100644 subgames/zeus/mods/auri_chat/script/api_server.lua create mode 100644 subgames/zeus/mods/auri_chat/script/category_icon.xcf create mode 100644 subgames/zeus/mods/auri_chat/script/gui.lua create mode 100644 subgames/zeus/mods/auri_chat/script/init.lua create mode 100644 subgames/zeus/mods/auri_chat/script/test.lua create mode 100644 subgames/zeus/mods/auri_chat/textures/chat_icon.png create mode 100644 subgames/zeus/mods/auri_chat/textures/commands_icon.png create mode 100644 subgames/zeus/mods/auri_chat/textures/debug_icon.png create mode 100644 subgames/zeus/mods/auri_world_edit/script/init.lua create mode 100644 subgames/zeus/mods/auri_world_edit/textures/wand.png create mode 100755 subgames/zeus/mods/zeus_flowers/textures/pink.png create mode 100644 subgames/zeus/mods/zeus_inventory/textures/player_frame.png diff --git a/assets/base/script/modules/string.lua b/assets/base/script/modules/string.lua index 3a634c16..6b7c924e 100644 --- a/assets/base/script/modules/string.lua +++ b/assets/base/script/modules/string.lua @@ -15,4 +15,16 @@ string.split = function(input, sep, op) for str in string.gmatch(input, '([^'..sep..']+)') do table.insert(t, op and op(str) or str) end return t +end + +-- string.escape +-- Escapes a string, replacing all graves with grave literals. +string.escape = function(str) + return str:gsub('%`', '``') +end + +-- string.starts_with +-- Checks if a string starts with the specified substring. +string.starts_with = function(str, substr) + return str:sub(1, substr:len()) == substr end \ No newline at end of file diff --git a/assets/base/script/modules/vector.lua b/assets/base/script/modules/vector.lua index 9eea73a9..9c162a03 100644 --- a/assets/base/script/modules/vector.lua +++ b/assets/base/script/modules/vector.lua @@ -50,7 +50,7 @@ vector.__unm = vector.negative -- vector.subtract -- Subtract v2 from v1 function vector.subtract(v1, v2) - return vector.add(v1, vector.negative(v2)) + return vector.add(v1, -v2) end vector.__sub = vector.subtract @@ -59,11 +59,8 @@ vector.__sub = vector.subtract -- Multiply v1 by a vector or number function vector.multiply(v1, m) assert(vector.is_vector(v1)) - if vector.is_vector(m) then - return create_vector(rawget(v1, 1) * rawget(m, 1), rawget(v1, 2) * rawget(m, 2), rawget(v1, 3) * rawget(m, 3)) - elseif type(m) == "number" then - return create_vector(rawget(v1, 1) * m, rawget(v1, 2) * m, rawget(v1, 3) * m) - end + if vector.is_vector(m) then return create_vector(rawget(v1, 1) * rawget(m, 1), rawget(v1, 2) * rawget(m, 2), rawget(v1, 3) * rawget(m, 3)) + elseif type(m) == "number" then return create_vector(rawget(v1, 1) * m, rawget(v1, 2) * m, rawget(v1, 3) * m) end end vector.__mul = vector.multiply @@ -176,10 +173,10 @@ end function vector:__tostring() return table.concat({ - "{ ", + "{", tostring(rawget(self, 1)), ", ", tostring(rawget(self, 2)), ", ", - tostring(rawget(self, 3)), " }" + tostring(rawget(self, 3)), "}" }) end @@ -202,7 +199,7 @@ vector.new = function(x, y, z) -- Invalid type passed to function, return nil elseif type(x) ~= "number" and type(x) ~= "table" then return nil -- Passed a table as x with at least x and y parameters, z will be set to table value or 0 - elseif type(x) == "table" and (x.__is_vector or (type(x[1]) == "number" and type(x[2]) == "number")) then return create_vector(x[1], x[2], x[3] or 0) + elseif type(x) == "table" and (vector.is_vector(x) or (type(x[1]) == "number" and type(x[2]) == "number")) then return create_vector(x[1], x[2], x[3] or 0) -- Only one number was passed, give a vector with all three values set to it elseif y == nil then return create_vector(x, x, x) -- Invalid type passed to function, return nil diff --git a/assets/shader/world/entity.fs b/assets/shader/world/entity.fs index d4f75275..13d13afe 100644 --- a/assets/shader/world/entity.fs +++ b/assets/shader/world/entity.fs @@ -15,11 +15,11 @@ uniform sampler2D tex; void main() { if (useTex > 0.5) { vec4 spec = texture(tex, colorData.xy) * vec4(colorBlend, colorData.w); - if (spec.a < 0.1) discard; + if (spec.a < 0.01) discard; gSpecular = spec; } else { - if (colorData.a < 0.1) discard; + if (colorData.a < 0.01) discard; gSpecular = colorData * vec4(colorBlend, 1); } gPosition = vec4(fragPos, 1); diff --git a/assets/textures/ui/font.png b/assets/textures/ui/font.png index ca0ad9fb87a861fac37bc2a3b2ccec05ad0338d7..870e4b5b73642444b407a577369b06fe5e7d953b 100644 GIT binary patch delta 1619 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 Sxz~Ui7(8A5T-G@yGywpZ^m0A` diff --git a/assets/textures/ui/font.xcf b/assets/textures/ui/font.xcf index 111791bf4dce87d9600a8e9da1951d6c55641deb..90477bda1d70346faeb15585f1586c2c3b7aae09 100644 GIT binary patch literal 16395 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 OgHd& boxes, float width) { - this->width = width; - buildMesh(boxes); + this->model->fromMesh(WireframeEntity::createMesh(boxes, width)); } - -void WireframeEntity::buildMesh(const std::vector& boxes) { - indOffset = 0; +uptr WireframeEntity::createMesh(const vec& boxes, f32 wireWidth, vec3 stroke, vec4 fill) { + vec indices {}; + indices.reserve(boxes.size() * 36 * (12 + fill.a ? 1 : 0)); + vec vertices {}; + vertices.reserve(boxes.size() * 8 * 12 + (fill.a ? 24 : 0)); - vertices.clear(); - indices.clear(); + for (const let& box : boxes) WireframeEntity::createSelectionBoxVertices( + box, wireWidth, vec4(stroke, 1), fill, vertices, indices); - for (auto& box : boxes) { - glm::vec3 a = box.a; - glm::vec3 b = box.b - box.a; - - createBox(a, b, 0, 0, 0, 0, b.y, 0); - createBox(a, b, b.x, 0, 0, 0, b.y, 0); - createBox(a, b, b.x, 0, b.z, 0, b.y, 0); - createBox(a, b, 0, 0, b.z, 0, b.y, 0); - - createBox(a, b, 0, 0, 0, b.x, 0, 0); - createBox(a, b, 0, b.y, 0, b.x, 0, 0); - createBox(a, b, 0, b.y, b.z, b.x, 0, 0); - createBox(a, b, 0, 0, b.z, b.x, 0, 0); - - createBox(a, b, 0, 0, 0, 0, 0, b.z); - createBox(a, b, 0, b.y, 0, 0, 0, b.z); - createBox(a, b, b.x, b.y, 0, 0, 0, b.z); - createBox(a, b, b.x, 0, 0, 0, 0, b.z); - } - - - std::unique_ptr mesh = std::make_unique(); + uptr mesh = make_unique(); mesh->create(vertices, indices); - this->model->fromMesh(std::move(mesh)); + return mesh; } -void -WireframeEntity::createBox(glm::vec3 a, glm::vec3 b, float x, float y, float z, float xSize, float ySize, float zSize) { - float hw = (width / 2.0f); - float w = width; - glm::vec3 c = color; +uptr WireframeEntity::createMesh(const SelectionBox& box, f32 wireWidth, vec3 stroke, vec4 fill) { + return WireframeEntity::createMesh(vec { box }, wireWidth, stroke, fill); +} + +void WireframeEntity::createSelectionBoxVertices(const SelectionBox& box, f32 wireWidth, + vec4 stroke, vec4 fill, vec& vertices, vec& indices) { - std::vector myVerts{ - /*0*/ - {{ x - hw + a.x, y - hw + a.y, z - hw + a.z }, { c.x, c.y, c.z, 1 }, { 1, 1, 1 }, false, { 0, 1, 0 }, {}, {}}, - /*1*/{{ x - hw + a.x + xSize + w, y - hw + a.y, z - hw + a.z }, { c.x, c.y, c.z, 1 }, { 1, 1, 1 }, false, - { 0, 1, 0 }, {}, {}}, - /*2*/ - {{ x - hw + a.x + xSize + w, y - hw + a.y, z - hw + a.z + zSize + w }, { c.x, c.y, c.z, 1 }, { 1, 1, 1 }, false, - { 0, 1, 0 }, {}, {}}, - /*3*/{{ x - hw + a.x, y - hw + a.y, z - hw + a.z + zSize + w }, { c.x, c.y, c.z, 1 }, { 1, 1, 1 }, false, - { 0, 1, 0 }, {}, {}}, + let& a = box.a; + let& b = box.b; + + createStrokeVertices({ a.x, a.y, a.z }, { b.x, a.y, a.z }, wireWidth, stroke, vertices, indices); + createStrokeVertices({ a.x, a.y, b.z }, { b.x, a.y, b.z }, wireWidth, stroke, vertices, indices); + createStrokeVertices({ a.x, a.y, a.z }, { a.x, a.y, b.z }, wireWidth, stroke, vertices, indices); + createStrokeVertices({ b.x, a.y, a.z }, { b.x, a.y, b.z }, wireWidth, stroke, vertices, indices); + + createStrokeVertices({ a.x, b.y, a.z }, { b.x, b.y, a.z }, wireWidth, stroke, vertices, indices); + createStrokeVertices({ a.x, b.y, b.z }, { b.x, b.y, b.z }, wireWidth, stroke, vertices, indices); + createStrokeVertices({ a.x, b.y, a.z }, { a.x, b.y, b.z }, wireWidth, stroke, vertices, indices); + createStrokeVertices({ b.x, b.y, a.z }, { b.x, b.y, b.z }, wireWidth, stroke, vertices, indices); + + createStrokeVertices({ a.x, a.y, a.z }, { a.x, b.y, a.z }, wireWidth, stroke, vertices, indices); + createStrokeVertices({ b.x, a.y, a.z }, { b.x, b.y, a.z }, wireWidth, stroke, vertices, indices); + createStrokeVertices({ b.x, a.y, b.z }, { b.x, b.y, b.z }, wireWidth, stroke, vertices, indices); + createStrokeVertices({ a.x, a.y, b.z }, { a.x, b.y, b.z }, wireWidth, stroke, vertices, indices); + + if (fill.a) { + vec3 nml = { 0, 1, 0 }; + f32 off = wireWidth / 2; + usize indOffset = vertices.size(); - /*4*/{{ x - hw + a.x, y - hw + a.y + ySize + w, z - hw + a.z }, { c.x, c.y, c.z, 1 }, { 1, 1, 1 }, false, - { 0, 1, 0 }, {}, {}}, - /*5*/ - {{ x - hw + a.x + xSize + w, y - hw + a.y + ySize + w, z - hw + a.z }, { c.x, c.y, c.z, 1 }, { 1, 1, 1 }, false, - { 0, 1, 0 }, {}, {}}, - /*6*/{{ x - hw + a.x + xSize + w, y - hw + a.y + ySize + w, z - hw + a.z + zSize + w }, { c.x, c.y, c.z, 1 }, - { 1, 1, 1 }, false, { 0, 1, 0 }, {}, {}}, - /*7*/ - {{ x - hw + a.x, y - hw + a.y + ySize + w, z - hw + a.z + zSize + w }, { c.x, c.y, c.z, 1 }, { 1, 1, 1 }, false, - { 0, 1, 0 }, {}, {}}, - }; + vertices.push_back({{ a.x, a.y, a.z - off }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ a.x, b.y, a.z - off }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ b.x, b.y, a.z - off }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ b.x, a.y, a.z - off }, fill, vec3(1), false, nml, {}, {}}); + + vertices.push_back({{ a.x, a.y, b.z + off }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ a.x, b.y, b.z + off }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ b.x, b.y, b.z + off }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ b.x, a.y, b.z + off }, fill, vec3(1), false, nml, {}, {}}); + + vertices.push_back({{ a.x - off, a.y, a.z }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ a.x - off, b.y, a.z }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ a.x - off, b.y, b.z }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ a.x - off, a.y, b.z }, fill, vec3(1), false, nml, {}, {}}); + + vertices.push_back({{ b.x + off, a.y, a.z }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ b.x + off, b.y, a.z }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ b.x + off, b.y, b.z }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ b.x + off, a.y, b.z }, fill, vec3(1), false, nml, {}, {}}); + + vertices.push_back({{ a.x, a.x - off, a.z }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ b.x, a.x - off, a.z }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ b.x, a.x - off, b.z }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ a.x, a.x - off, b.z }, fill, vec3(1), false, nml, {}, {}}); + + vertices.push_back({{ a.x, b.y + off, a.z }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ b.x, b.y + off, a.z }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ b.x, b.y + off, b.z }, fill, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ a.x, b.y + off, b.z }, fill, vec3(1), false, nml, {}, {}}); + + const static array boxIndices { + 0, 1, 2, 2, 3, 0, + 4, 7, 6, 6, 5, 4, + 8, 11, 10, 10, 9, 8, + 12, 13, 14, 14, 15, 12, + 16, 17, 18, 18, 19, 16, + 20, 23, 22, 22, 21, 20 + }; + + for (u32 i : boxIndices) indices.push_back(i + indOffset); + } +} + +void WireframeEntity::createStrokeVertices(vec3 a, vec3 b, f32 wireWidth, + vec4 color, vec& vertices, vec& indices) { - std::vector myInds{ + f32 off = wireWidth / 2.f; + vec3 nml = { 0, 1, 0 }; + usize indOffset = vertices.size(); + + vertices.push_back({{ a.x - off, a.y - off, a.z - off }, color, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ b.x + off, a.y - off, a.z - off }, color, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ b.x + off, a.y - off, b.z + off }, color, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ a.x - off, a.y - off, b.z + off }, color, vec3(1), false, nml, {}, {}}); + + vertices.push_back({{ a.x - off, b.y + off, a.z - off }, color, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ b.x + off, b.y + off, a.z - off }, color, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ b.x + off, b.y + off, b.z + off }, color, vec3(1), false, nml, {}, {}}); + vertices.push_back({{ a.x - off, b.y + off, b.z + off }, color, vec3(1), false, nml, {}, {}}); + + const static array boxIndices { 0, 1, 2, 2, 3, 0, 4, 7, 6, 6, 5, 4, 0, 4, 5, 5, 1, 0, @@ -82,8 +117,5 @@ WireframeEntity::createBox(glm::vec3 a, glm::vec3 b, float x, float y, float z, 1, 5, 6, 6, 2, 1, }; - vertices.insert(vertices.end(), myVerts.begin(), myVerts.end()); - for (auto i : myInds) indices.push_back(i + indOffset); - - indOffset += 8; + for (u32 i : boxIndices) indices.push_back(i + indOffset); } \ No newline at end of file diff --git a/src/client/entity/WireframeEntity.h b/src/client/entity/WireframeEntity.h index 62ca3352..72503344 100644 --- a/src/client/entity/WireframeEntity.h +++ b/src/client/entity/WireframeEntity.h @@ -1,7 +1,3 @@ -// -// Created by aurailus on 08/04/19. -// - #pragma once #include "world/dim/ent/DrawableEntity.h" @@ -11,22 +7,24 @@ class WireframeEntity : public DrawableEntity { public: - WireframeEntity(SubgamePtr game, DimensionPtr dim, glm::vec3 color) : - DrawableEntity(game, dim, std::make_shared()), Entity(game, dim), - color(color) {}; + WireframeEntity(SubgamePtr game, DimensionPtr dim, vec3 stroke, vec4 fill = vec4(0)) : + DrawableEntity(game, dim, std::make_shared()), Entity(game, dim), stroke(stroke), fill(fill) {}; - void updateMesh(const std::vector& boxes, float width); + void updateMesh(const vec& boxes, f32 width); + + static uptr createMesh(const vec& boxes, + f32 wireWidth, vec3 stroke = vec3(1), vec4 fill = vec4(0)); + + static uptr createMesh(const SelectionBox& box, + f32 wireWidth, vec3 stroke = vec3(1), vec4 fill = vec4(0)); private: - std::vector vertices{}; - std::vector indices{}; + static void createSelectionBoxVertices(const SelectionBox& box, f32 wireWidth, + vec4 stroke, vec4 fill, vec& vertices, vec& indices); - void buildMesh(const std::vector& boxes); + static void createStrokeVertices(vec3 a, vec3 b, f32 wireWidth, + vec4 color, vec& vertices, vec& indices); - void createBox(glm::vec3 a, glm::vec3 b, float x, float y, float z, float xSize, float ySize, float zSize); - - glm::vec3 color{}; - - float width = 0.5; - int indOffset = 0; + vec3 stroke {}; + vec4 fill {}; }; diff --git a/src/client/graph/Renderer.cpp b/src/client/graph/Renderer.cpp index 66fc908b..f2e88ffe 100644 --- a/src/client/graph/Renderer.cpp +++ b/src/client/graph/Renderer.cpp @@ -93,6 +93,8 @@ void Renderer::beginChunkDeferredCalls() { } void Renderer::beginEntityDeferredCalls() { + glEnable(GL_BLEND); + currentModelUniform = entity.uniforms.model; setShader(entity); @@ -101,6 +103,8 @@ void Renderer::beginEntityDeferredCalls() { } void Renderer::endDeferredCalls() { + glDisable(GL_BLEND); + activeTexture = nullptr; glBindFramebuffer(GL_FRAMEBUFFER, ssao.fbo); @@ -154,6 +158,7 @@ void Renderer::endDeferredCalls() { glBindTexture(GL_TEXTURE_2D, blur.colorBuffer); glEnable(GL_BLEND); + renderQuad(); } diff --git a/src/client/gui/DebugGui.cpp b/src/client/gui/DebugGui.cpp index 70b0ac6c..b1ffc1f1 100644 --- a/src/client/gui/DebugGui.cpp +++ b/src/client/gui/DebugGui.cpp @@ -21,11 +21,11 @@ DebugGui::DebugGui(u16vec2 buffer, SubgamePtr game, LocalWorld& world, vectextures, fontRef); auto crosshairText = make_shared("crosshairText"); - crosshairText->create({ 2, 2 }, {}, { 0.2, 0.2, 0.2, 0.5 }, { 1, 1, 1, 1 }, f); + crosshairText->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, { 0.2, 0.2, 0.2, 0.5 }, f); add(crosshairText); auto dataText = make_shared("dataText"); - dataText->create({ 2, 2 }, {}, { 0.2, 0.2, 0.2, 0.5 }, { 1, 1, 1, 1 }, f); + dataText->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, { 0.2, 0.2, 0.2, 0.5 }, f); add(dataText); auto interpGraph = make_shared("interpGraph"); @@ -219,7 +219,8 @@ void DebugGui::update(sptr player, f64 delta, u32 interpolatedChunk if (target.type == Target::Type::BLOCK) { const auto& def = game->getDefs().blockFromId(world.getActiveDimension()->getBlock(target.data.block.pos)); - get("crosshairText")->setText(def.name + " (" + def.identifier + ") [" + std::to_string(def.index) + "]"); + get("crosshairText")->setText( + "`b" + def.name + " (`r` `c7" + def.identifier + "`cr - " + std::to_string(def.index) + "` `b)"); } else { get("crosshairText")->setText(""); diff --git a/src/client/gui/basic/GuiInventoryItem.cpp b/src/client/gui/basic/GuiInventoryItem.cpp index a396a5e6..ab50fccf 100644 --- a/src/client/gui/basic/GuiInventoryItem.cpp +++ b/src/client/gui/basic/GuiInventoryItem.cpp @@ -43,7 +43,7 @@ void GuiInventoryItem::create(glm::vec2 scale, unsigned short count, ItemDef& de if (count > 1) { auto text = std::make_shared("count"); - text->create(scale, {}, {}, { 1, 1, 1, 1 }, f); + text->create(scale, {}, { 1, 1, 1, 1 }, {}, f); text->setText(std::to_string(count)); add(text); text->setPos({ (19 - text->getWidth()) * scale.x, 9 * scale.y }); diff --git a/src/client/gui/basic/GuiText.cpp b/src/client/gui/basic/GuiText.cpp index a98f7702..e9407ed9 100644 --- a/src/client/gui/basic/GuiText.cpp +++ b/src/client/gui/basic/GuiText.cpp @@ -1,9 +1,3 @@ -// -// Created by aurailus on 25/12/18. -// - -#include - #include "GuiText.h" #include "util/Util.h" @@ -12,178 +6,260 @@ #include "game/atlas/asset/AtlasRef.h" #include "world/dim/ent/AnimationSegment.h" -GuiText::GuiText(const std::string& key) : GuiComponent(key) {} - -void GuiText::create(glm::vec2 scale, glm::vec4 padding, glm::vec4 bgcolor, glm::vec4 color, Font font) { - // Text Constructor - // Creates a GuiText object. - - this->scale = scale; +void GuiText::create(vec2 scale, vec4 padding, vec4 textColor, vec4 backgroundColor, Font font) { this->padding = padding; this->font = std::move(font); - this->bgcolor = bgcolor; - this->color = color; + this->textColor = textColor; + this->backgroundColor = backgroundColor; - setScale(scale); setText(""); + setScale(scale); } -std::shared_ptr GuiText::fromSerialized(const LuaGuiElement& elem, TextureAtlas& textures, glm::ivec2 bounds) { - glm::vec2 pos = SerialGui::get(elem, "position", bounds); - glm::vec2 offset = SerialGui::get(elem, "position_anchor"); - glm::vec2 size = SerialGui::get(elem, "size", bounds); - glm::vec4 padding = SerialGui::get(elem, "padding", bounds); - glm::vec2 scale = SerialGui::get(elem, "scale"); - if (scale == glm::vec2{ 0, 0 }) scale = { 1, 1 }; - +sptr GuiText::fromSerialized(const LuaGuiElement& elem, TextureAtlas& textures, ivec2 bounds) { + vec2 pos = SerialGui::get(elem, "position", bounds); + vec2 offset = SerialGui::get(elem, "position_anchor"); + vec2 size = SerialGui::get(elem, "size", bounds); + vec4 padding = SerialGui::get(elem, "padding", bounds); + vec2 scale = SerialGui::get(elem, "scale") * vec2(0.33); + + if (scale.x == 0 && scale.y == 0) scale = vec2 { 1, 1 }; pos -= offset * size; - - glm::vec4 background_color = Util::hexToColorVec(elem.get_or("background", "#0000")); - glm::vec4 color = Util::hexToColorVec(elem.get_or("color", "#fff")); - std::string content = elem.get_or("content", ""); - + + vec4 backgroundColor = Util::hexToColorVec(elem.get_or("background", "#0000")); + vec4 textColor = Util::hexToColorVec(elem.get_or("color", "#fff")); + string content = elem.get_or("content", ""); + auto text = std::make_shared(elem.key); - text->create(scale * SerialGui::SCALE_MODIFIER, padding, background_color, color, { textures, textures["font"] }); + text->create(scale * SerialGui::SCALE_MODIFIER, padding, + textColor, backgroundColor, { textures, textures["font"] }); text->setText(content); text->setPos(pos); - + return text; } -void GuiText::setText(std::string text) { - this->text = std::move(text); - unsigned int indOffset = 0; +void GuiText::setText(string newText) { + text = newText; + u32 ind = 0; - maxLineWidth = 0; + width = 0; - std::vector textVertices; - textVertices.reserve(text.length() * 8 + 200); - std::vector textIndices; - textIndices.reserve(text.length() * 12 + 240); + vec vertices; + vertices.reserve(text.length() * 8 + 200); + vec indices; + indices.reserve(text.length() * 12 + 240); - //Draw background & Measure Line Width - int lineWidth = 0; - int xOffset = 0, yOffset = 0; - int h = Font::charHeight; - - for (unsigned int i = 0; i < this->text.length() + 1; i++) { - char c = this->text[i]; - - //TODO: Proper font handling. - if (c == '\t') c = ' '; - - if (c == '\n' || i == this->text.length()) { - if (lineWidth > 0) { - lineWidth += 2; - - if (lineWidth > maxLineWidth) maxLineWidth = lineWidth; - - if (bgcolor.w != 0) { - textVertices.emplace_back(glm::vec3{ -1, yOffset - 1, 0 }, bgcolor, glm::vec3(1), 0.f, glm::vec3{}, - glm::ivec4{}, glm::vec4{}); - textVertices.emplace_back(glm::vec3{ -1, yOffset + h + 1, 0 }, bgcolor, glm::vec3(1), 0.f, - glm::vec3{}, glm::ivec4{}, glm::vec4{}); - textVertices.emplace_back(glm::vec3{ lineWidth + 1, yOffset + h + 1, 0 }, bgcolor, glm::vec3(1), - 0.f, glm::vec3{}, glm::ivec4{}, glm::vec4{}); - textVertices.emplace_back(glm::vec3{ lineWidth + 1, yOffset - 1, 0 }, bgcolor, glm::vec3(1), 0.f, - glm::vec3{}, glm::ivec4{}, glm::vec4{}); - - textIndices.emplace_back(indOffset); - textIndices.emplace_back(indOffset + 1); - textIndices.emplace_back(indOffset + 2); - textIndices.emplace_back(indOffset + 2); - textIndices.emplace_back(indOffset + 3); - textIndices.emplace_back(indOffset); - - indOffset += 4; - } - yOffset += h + 2; - } - else { - yOffset += h / 2; //Pad out the height if using just newlines. - } - - lineWidth = 0; - } - else lineWidth += font.getCharWidth(c) + 1; + vec lines; + { + std::stringstream textStream(text); + string line; + while (std::getline(textStream, line, '\n')) lines.emplace_back(line); } - //Draw Characters + vec3 offset = {}; + u32 h = Font::charHeight; - bool emptyLine = true; - xOffset = 0; - yOffset = 0; + bool bold = false; + bool italic = false; + i32 underline = -1; + i32 strikethrough = -1; + u32 strikethroughVertStart = 0; + vec4 color = textColor; - for (unsigned int i = 0; i < this->text.length() + 1; i++) { - char c = this->text[i]; + for (usize i = 0; i < lines.size(); i++) { + let& line = lines[i]; + bool empty = line.find_first_not_of(" \t\n") == -1; - //TODO: Proper font handling. - if (c == '\t') c = ' '; - - unsigned int h = Font::charHeight; - - if (c == '\n' || i == this->text.length()) { - yOffset += (emptyLine) ? h / 2 : h + 2; - xOffset = 0; - emptyLine = true; + if (empty) { + offset.x = 0; + offset.y += h / 2; continue; } - else { - emptyLine = false; + + u32 bgVertStart = 0; + if (backgroundColor.w != 0) { + bgVertStart = vertices.size(); + for (u32 i = 0; i < 4; i++) vertices.push_back({}); + for (u32 i : INDICES) indices.push_back(i + ind); + ind += 4; } - - auto charWidth = font.getCharWidth(c) + 1; - auto charUVs = font.getCharUVs(c); - - for (unsigned int j = 0; j <= 1; j++) { - glm::vec3 c = { this->color.x, this->color.y, this->color.z }; + + for (usize j = 0; j < line.length() + 1; j++) { + char c = j < line.length() ? line[j] : ' '; + if (c == '\t') c = ' '; - if (j == 0) { - c *= glm::vec3{ 0.4, 0.4, 0.45 }; - xOffset += 1; - yOffset += 1; - } - else { - xOffset -= 1; - yOffset -= 1; + if (c == '`') { + bool flushDecorators = j == line.length(); + + char d = line[++j]; + if (d == '`') goto escape_formatting; + else if (d == ' ') offset.x++; + else if (d == 'b') bold = true; + else if (d == 'i') italic = true; + else if (d == 'u') underline = offset.x; + else if (d == 's') { + strikethrough = offset.x; + strikethroughVertStart = vertices.size(); + for (u32 i = 0; i < 4; i++) vertices.push_back({}); + for (u32 i : INDICES) indices.push_back(i + ind); + ind += 4; + } + else if (d == 'c') flushDecorators = true; + else if (d == 'r') { + bold = false; + italic = false; + flushDecorators = true; + } + + if (flushDecorators) { + if (underline != -1) { + GuiText::drawRect({ underline, h - 1, offset.x, h }, color, vertices, indices, ind); + GuiText::drawRect({ underline + 1, h, offset.x + 1, h + 1 }, + color * BG_MULTIPLE, vertices, indices, ind); + underline = offset.x; + } + + if (strikethrough != -1) { + GuiText::drawRect({ strikethrough, h / 2, offset.x, h / 2 + 1 }, + color, vertices, indices, ind); + GuiText::drawRect({ strikethrough + 1, h / 2 + 1, offset.x + 1, h / 2 + 2 }, + color * BG_MULTIPLE, vertices, indices, ind, strikethroughVertStart); + strikethrough = offset.x; + } + + if (d == 'r') { + color = textColor; + underline = -1; + strikethrough = -1; + } + } + + if (d == 'c') { + char code = line[++j]; + if (code == 'r') color = textColor; + else { + u32 v; + std::stringstream ss; + ss << std::hex << code; + ss >> v; + color = COLORS[v]; + } + } + + continue; } - textVertices.emplace_back(glm::vec3{ xOffset, yOffset, 0 }, glm::vec4{ charUVs.x, charUVs.y, 0, color.w }, - c, 1.f, glm::vec3{}, glm::ivec4{}, glm::vec4{}); - textVertices.emplace_back(glm::vec3{ xOffset, yOffset + h, 0 }, - glm::vec4{ charUVs.x, charUVs.w, 0, color.w }, c, 1.f, glm::vec3{}, glm::ivec4{}, glm::vec4{}); - textVertices.emplace_back(glm::vec3{ xOffset + charWidth, yOffset + h, 0 }, - glm::vec4{ charUVs.z, charUVs.w, 0, color.w }, c, 1.f, glm::vec3{}, glm::ivec4{}, glm::vec4{}); - textVertices.emplace_back(glm::vec3{ xOffset + charWidth, yOffset, 0 }, - glm::vec4{ charUVs.z, charUVs.y, 0, color.w }, c, 1.f, glm::vec3{}, glm::ivec4{}, glm::vec4{}); - - textIndices.emplace_back(indOffset); - textIndices.emplace_back(indOffset + 1); - textIndices.emplace_back(indOffset + 2); - textIndices.emplace_back(indOffset + 2); - textIndices.emplace_back(indOffset + 3); - textIndices.emplace_back(indOffset); - - indOffset += 4; + escape_formatting: + if (j == line.length()) continue; + + u32 w = font.getCharWidth(c) + 1; + vec4 UV = font.getCharUVs(c); + + for (u32 k = 0; k < (bold ? 4 : 2); k++) { + vec4 c = color; + + if (k == 0 || (k == 1 && bold)) c *= BG_MULTIPLE; + + if (k == 0) { + offset.x += 1; + offset.y += 1; + } + else if ((k == 1 || k == 3) && bold) { + offset.x += 1; + } + else if ((k == 1 && !bold) || (k == 2 && bold)) { + offset.x -= bold ? 2 : 1; + offset.y -= 1; + } + + vertices.emplace_back(offset + vec3(italic ? 2 : 0, 0, 0), vec4 { UV.x, UV.y, 0, c.w }, + vec3(c), 1.f, vec3 {}, ivec4 {}, vec4 {}); + + vertices.emplace_back(offset + vec3(0, h, 0), vec4 { UV.x, UV.w, 0, c.w }, + vec3(c), 1.f, vec3 {}, ivec4 {}, vec4 {}); + + vertices.emplace_back(offset + vec3(w, h, 0), vec4 { UV.z, UV.w, 0, c.w }, + vec3(c), 1.f, vec3 {}, ivec4 {}, vec4 {}); + + vertices.emplace_back(offset + vec3(w + (italic ? 2 : 0), 0, 0), vec4 { UV.z, UV.y, 0, c.w }, + vec3(c), 1.f, vec3 {}, ivec4 {}, vec4 {}); + + for (u32 i : INDICES) indices.push_back(i + ind); + ind += 4; + } + + offset.x += w; } - xOffset += charWidth; + if (backgroundColor.w != 0) GuiText::drawRect({ -1, offset.y - 1, offset.x + 2, offset.y + h + 1 }, + backgroundColor, vertices, indices, ind, bgVertStart); + + if (offset.x > width) width = offset.x; + offset.x = 0; + offset.y += h + 2; } - auto m = std::make_unique(); - m->create(textVertices, textIndices); + let m = make_unique(); + m->create(vertices, indices); - auto model = std::make_shared(); + let model = make_shared(); model->fromMesh(std::move(m)); entity.setModel(model); } -std::string GuiText::getText() { +string GuiText::getText() { return text; } -unsigned int GuiText::getWidth() { - return maxLineWidth; +u32 GuiText::getWidth() { + return width; } + +void GuiText::drawRect(const vec4 pos, const vec4 color, + vec& vertices, vec& indices, u32& ind, const u32 insert) { + + vec myVerts = { + { vec3 { pos.x, pos.y, 0 }, color, vec3(1), 0.f, vec3 {}, ivec4 {}, vec4 {} }, + { vec3 { pos.x, pos.w, 0 }, color, vec3(1), 0.f, vec3 {}, ivec4 {}, vec4 {} }, + { vec3 { pos.z, pos.w, 0 }, color, vec3(1), 0.f, vec3 {}, ivec4 {}, vec4 {} }, + { vec3 { pos.z, pos.y, 0 }, color, vec3(1), 0.f, vec3 {}, ivec4 {}, vec4 {} } + }; + + if (insert != -1) { + vertices[insert] = myVerts[0]; + vertices[insert + 1] = myVerts[1]; + vertices[insert + 2] = myVerts[2]; + vertices[insert + 3] = myVerts[3]; + } + else { + for (EntityVertex& vert : myVerts) vertices.emplace_back(vert); + for (u32 i : INDICES) indices.push_back(i + ind); + ind += 4; + } +} + +const array GuiText::COLORS = { + Util::hexToColorVec("#000000"), + Util::hexToColorVec("#0000AA"), + Util::hexToColorVec("#00AA00"), + Util::hexToColorVec("#00AAAA"), + Util::hexToColorVec("#AA0000"), + Util::hexToColorVec("#b05cff"), + Util::hexToColorVec("#FFAA00"), + Util::hexToColorVec("#cccccc"), + Util::hexToColorVec("#555555"), + Util::hexToColorVec("#33a2f5"), + Util::hexToColorVec("#9fff80"), + Util::hexToColorVec("#7df4ff"), + Util::hexToColorVec("#ff739f"), + Util::hexToColorVec("#fd7dff"), + Util::hexToColorVec("#fffb82"), + Util::hexToColorVec("#ffffff") +}; + +const array GuiText::INDICES = { 0, 1, 2, 2, 3, 0 }; + +const vec4 GuiText::BG_MULTIPLE = { 0.3, 0.3, 0.35, 0.75 }; \ No newline at end of file diff --git a/src/client/gui/basic/GuiText.h b/src/client/gui/basic/GuiText.h index 46b6dbcd..1e2dd8aa 100644 --- a/src/client/gui/basic/GuiText.h +++ b/src/client/gui/basic/GuiText.h @@ -1,7 +1,3 @@ -// -// Created by aurailus on 25/12/18. -// - #pragma once #include "client/gui/GuiComponent.h" @@ -9,32 +5,58 @@ #include "client/graph/Font.h" class TextureAtlas; - class LuaGuiElement; +/** + * Renders text, with formatting escape codes. + * + * `` - Raw grave character + * ` - Single pixel space + * `c[0-f] - Preset colors + * `cr - Reset to the global text color + * `#[hex code] - Color with an arbitrary hex code + * `b - Bold + * `i - Italic + * `u - Underline + * `s - Strikethrough + * `r - Reset to default formatting + */ + class GuiText : public GuiComponent { - public: +public: GuiText() = default; - explicit GuiText(const std::string& key); + explicit GuiText(const string& key) : GuiComponent(key) {}; + + /** Creates a text component from a serialized lua element. */ + static sptr fromSerialized(const LuaGuiElement& elem, TextureAtlas& textures, ivec2 bounds); + + /** Creates a new text component. */ + void create(vec2 scale, vec4 padding, vec4 textColor, vec4 backgroundColor, Font font); + + /** Returns the width in display pixels of the text. */ + u32 getWidth(); - static std::shared_ptr - fromSerialized(const LuaGuiElement& elem, TextureAtlas& textures, glm::ivec2 bounds); + /** Sets the text to the string provided. */ + void setText(string text); - void create(glm::vec2 scale, glm::vec4 padding, glm::vec4 bgcolor, glm::vec4 color, Font font); + /** Returns the current text string. */ + string getText(); - unsigned int getWidth(); - - void setText(std::string text); - - std::string getText(); - - private: +private: Font font; - glm::vec4 bgcolor{}; - glm::vec4 color{}; - std::string text; - unsigned int maxLineWidth = 0; + void drawRect(const vec4 pos, const vec4 color, + vec& vertices, vec& indices, u32& ind, const u32 insert = -1); + + string text; + vec4 textColor {}; + vec4 backgroundColor {}; + + u32 width = 0; + + static const array COLORS; + static const array INDICES; + static const vec4 BG_MULTIPLE; }; diff --git a/src/client/gui/compound/GuiCellGraph.cpp b/src/client/gui/compound/GuiCellGraph.cpp index 35c64e05..990b18a3 100644 --- a/src/client/gui/compound/GuiCellGraph.cpp +++ b/src/client/gui/compound/GuiCellGraph.cpp @@ -18,7 +18,7 @@ void GuiCellGraph::create(f32 scale, vec4 padding, u16 count, const string& titl add(background); let label = make_shared(); - label->create({ 2, 2 }, {}, {}, { 1, 1, 1, 1 }, this->font); + label->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, {}, this->font); label->setPos({ 4, 8 }); label->setText(title); add(label); diff --git a/src/client/gui/compound/GuiLabelledGraph.cpp b/src/client/gui/compound/GuiLabelledGraph.cpp index d1e873f6..059521a7 100644 --- a/src/client/gui/compound/GuiLabelledGraph.cpp +++ b/src/client/gui/compound/GuiLabelledGraph.cpp @@ -34,7 +34,7 @@ void GuiLabelledGraph::create(glm::vec2 scale, glm::vec4 padding, const std::str graph->setPos({ GRAPH_PAD_X, GRAPH_PAD_Y }); auto label = std::make_shared("label"); - label->create({ 2, 2 }, {}, {}, { 1, 1, 1, 1 }, this->font); + label->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, {}, this->font); add(label); label->setPos({ TEXT_PAD_X, TEXT_PAD_Y }); diff --git a/src/client/gui/compound/GuiPerfGraph.cpp b/src/client/gui/compound/GuiPerfGraph.cpp index 7d3b8ccb..0c6b957e 100644 --- a/src/client/gui/compound/GuiPerfGraph.cpp +++ b/src/client/gui/compound/GuiPerfGraph.cpp @@ -30,15 +30,14 @@ void GuiPerfGraph::create(f32 scale, vec4 padding, const vec& sections, meter->setPos({ GRAPH_PAD_X, GRAPH_PAD_Y }); auto label = std::make_shared("label"); - label->create({ 2, 2 }, {}, {}, { 1, 1, 1, 1 }, this->font); + label->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, {}, this->font); label->setText(title); add(label); label->setPos({ TEXT_PAD_X, TEXT_PAD_Y }); for (usize i = 0; i < sections.size(); i++) { auto label = std::make_shared(); - label->create({ 2, 2 }, {}, vec4(GuiMeter::COLORS[i % GuiMeter::COLORS.size()], 1), - { 1, 1, 1, 1 }, this->font); + label->create({ 2, 2 }, {}, vec4(GuiMeter::COLORS[i % GuiMeter::COLORS.size()], 1), {}, this->font); label->setText(sections[i]); add(label); label->setPos({ TEXT_PAD_X + scale * (i % 2) / 2, TEXT_PAD_Y + GRAPH_PAD_Y + (i / 2) * 24 + 2 }); diff --git a/src/client/scene/ConnectScene.cpp b/src/client/scene/ConnectScene.cpp index 6ed59d61..4f272df3 100644 --- a/src/client/scene/ConnectScene.cpp +++ b/src/client/scene/ConnectScene.cpp @@ -33,7 +33,7 @@ ConnectScene::ConnectScene(Client& client, Address addr) : Scene(client), Font f(client.game->textures, client.game->textures["font"]); auto statusText = std::make_shared("statusText"); - statusText->create({ 2, 2 }, {}, {}, { 1, 1, 1, 1 }, f); + statusText->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, {}, f); statusText->setText("Connecting..."); statusText->setPos({ 32, 24 }); components.add(statusText); diff --git a/src/client/scene/MainMenuScene.cpp b/src/client/scene/MainMenuScene.cpp index 3e331f04..4c0084ba 100644 --- a/src/client/scene/MainMenuScene.cpp +++ b/src/client/scene/MainMenuScene.cpp @@ -34,12 +34,12 @@ MainMenuScene::MainMenuScene(Client& client) : components->add(branding); { auto zephaText = make_shared("zephaText"); - zephaText->create({ GS, GS }, {}, {}, { 1, 1, 1, 1 }, f); + zephaText->create({ GS, GS }, {}, { 1, 1, 1, 1 }, {}, f); zephaText->setText("Zepha"); branding->add(zephaText); auto alphaText = make_shared("alphaText"); - alphaText->create({ GS, GS }, {}, {}, { 1, 0.5, 0.7, 1 }, f); + alphaText->create({ GS, GS }, {}, { 1, 0.5, 0.7, 1 }, {}, f); alphaText->setText("ALPHA"); alphaText->setPos({ 25 * GS, 0 }); branding->add(alphaText); diff --git a/src/game/atlas/TextureAtlas.cpp b/src/game/atlas/TextureAtlas.cpp index 76d36f3a..42ba257d 100644 --- a/src/game/atlas/TextureAtlas.cpp +++ b/src/game/atlas/TextureAtlas.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "TextureAtlas.h" @@ -181,7 +183,7 @@ std::shared_ptr TextureAtlas::generateTexture(std::string req) { std::string paramsString = req.substr(paramsBegin + 1, paramsEnd - paramsBegin - 1); std::vector params; - std::string::size_type pos = 0; + std::string::size_type pos; while ((pos = paramsString.find(',')) != std::string::npos) { params.push_back(paramsString.substr(0, pos)); paramsString.erase(0, pos + 1); @@ -197,9 +199,22 @@ std::shared_ptr TextureAtlas::generateTexture(std::string req) { auto data = getBytesAtPos({ src->pos.x + loc.x, src->pos.y + loc.y }, { loc.z, loc.w }).data; return addImage(data, req, false, loc.z, loc.w); } + else if (paramName == "multiply") { + if (params.size() != 2) throw std::runtime_error("multiply() requires 2 parameters."); + vec4 multiple = Util::hexToColorVec(params[1]); + auto tex = getBytesOfTex(params[0]); + + for (int i = 0; i < tex.width * tex.height; i++) { + tex.data[i * 4 + 0] *= multiple.x; + tex.data[i * 4 + 1] *= multiple.y; + tex.data[i * 4 + 2] *= multiple.z; + tex.data[i * 4 + 3] *= multiple.w; + } + + return addImage(tex.data, req, false, tex.width, tex.height); + } else { throw std::runtime_error("Invalid parameter."); - return nullptr; } } @@ -236,7 +251,6 @@ TextureAtlas::RawTexData TextureAtlas::getBytesAtPos(glm::ivec2 pos, glm::ivec2 } data.data = pixels; - return data; } diff --git a/src/lua/usertype/Dimension.cpp b/src/lua/usertype/Dimension.cpp index 609052a4..9df9751a 100644 --- a/src/lua/usertype/Dimension.cpp +++ b/src/lua/usertype/Dimension.cpp @@ -65,11 +65,14 @@ sol::table Api::Usertype::Dimension::add_entity_c(sol::this_state s, glm::vec3 p auto displayType = luaEntity.get>("display"); if (!displayType) throw std::runtime_error("entity '" + identifier + "' is missing the display property."); - auto displayObject = luaEntity.get>("display_object"); - if (!displayObject) throw std::runtime_error("entity '" + identifier + "' is missing the display_object property."); + auto displayObject = luaEntity.get>( + (*displayType == "wireframe") ? "display_stroke" : "display_object"); + if (!displayObject) throw std::runtime_error( + "entity '" + identifier + "' is missing the display_object/display_color property."); - auto displayTexture = luaEntity.get>("display_texture"); - if (strncmp(displayType->data(), "model", 5) == 0 && !displayTexture) + auto displayTexture = luaEntity.get>( + (*displayType == "wireframe") ? "display_fill" : "display_texture"); + if (displayType == "model" && !displayTexture) throw std::runtime_error("entity '" + identifier + "' is missing the display_texture property."); auto entity = std::make_shared<::LocalLuaEntity>(dim->getGame(), dim); @@ -105,11 +108,13 @@ sol::table Api::Usertype::Dimension::add_entity_s(sol::this_state s, glm::vec3 p auto displayType = luaEntity.get>("display"); if (!displayType) throw std::runtime_error("entity '" + identifier + "' is missing the display property."); - auto displayObject = luaEntity.get>("display_object"); - if (!displayObject) throw std::runtime_error("entity '" + identifier + "' is missing the display_object property."); + auto displayObject = luaEntity.get>( + (*displayType == "wireframe") ? "display_color" : "display_object"); + if (!displayObject) throw std::runtime_error( + "entity '" + identifier + "' is missing the display_object/display_color property."); auto displayTexture = luaEntity.get>("display_texture"); - if (strncmp(displayType->data(), "model", 5) == 0 && !displayTexture) + if (displayType == "model" && !displayTexture) throw std::runtime_error("entity '" + identifier + "' is missing the display_texture property."); unsigned int ind = dim->nextEntityInd(); diff --git a/src/lua/usertype/Entity.cpp b/src/lua/usertype/Entity.cpp index b2ccd7b8..27552651 100644 --- a/src/lua/usertype/Entity.cpp +++ b/src/lua/usertype/Entity.cpp @@ -141,16 +141,18 @@ void Api::Usertype::Entity::snap_roll(float rot) { entity->setRotateZ(rot); } -float Api::Usertype::Entity::get_scale() { - return entity->getScale().x; +glm::vec3 Api::Usertype::Entity::get_scale() { + return entity->getScale(); } -void Api::Usertype::Entity::set_scale(float scale) { - entity->setScale(scale); +void Api::Usertype::Entity::set_scale(sol::object scale) { + if (scale.is()) entity->setScale(scale.as()); + else entity->setScale(scale.as()); } -void Api::Usertype::Entity::snap_scale(float scale) { - entity->setScale(scale); +void Api::Usertype::Entity::snap_scale(sol::object scale) { + if (scale.is()) entity->setScale(scale.as()); + else entity->setScale(scale.as()); } Api::Usertype::Dimension Api::Usertype::Entity::get_dimension() { @@ -179,6 +181,9 @@ void Api::Usertype::Entity::set_display_type(const std::string& mode, else if (mode == "model" && argB) { entity->setAppearance("model", argA, *argB); } + else if (mode == "wireframe") { + entity->setAppearance("wireframe", argA, argB ? *argB : ""); + } else throw std::runtime_error("Invalid display type parameters."); } diff --git a/src/lua/usertype/Entity.h b/src/lua/usertype/Entity.h index c5debe1c..47c762bb 100644 --- a/src/lua/usertype/Entity.h +++ b/src/lua/usertype/Entity.h @@ -166,7 +166,7 @@ namespace Api::Usertype { * @returns the scale multiplier of the entity's model. */ - float get_scale(); + glm::vec3 get_scale(); /** * Sets the scale of the entity's model, @@ -174,14 +174,14 @@ namespace Api::Usertype { * @param scale - The desired scale multiplier. */ - void set_scale(float scale); + void set_scale(sol::object scale); /** * Sets the scale of the entity's model, without any interpolation. * @param scale - The desired scale multiplier. */ - void snap_scale(float scale); + void snap_scale(sol::object scale); /** * Gets the entity's true visual-offset, which may be different from diff --git a/src/lua/usertype/LuaGuiElement.cpp b/src/lua/usertype/LuaGuiElement.cpp index d57afe94..513df659 100644 --- a/src/lua/usertype/LuaGuiElement.cpp +++ b/src/lua/usertype/LuaGuiElement.cpp @@ -80,8 +80,8 @@ sol::object LuaGuiElement::get_child(sol::this_state s, sol::object key) { void LuaGuiElement::append(sol::this_state s, sol::object elem) { if (elem.is>()) children.push_back(elem.as>()); - else if (elem.is()) - children.push_back(call(s, elem.as()).as>()); + else if (elem.is()) + children.push_back(call(s, elem.as()).as>()); else throw std::runtime_error("Append arg is not an element or a function to generate one."); children.back()->parent = this; @@ -124,6 +124,16 @@ void LuaGuiElement::remove(sol::this_state s, sol::object elem) { } } +void LuaGuiElement::clear(sol::this_state s) { + for (auto it = children.cbegin(); it != children.cend();) { + (*it)->parent = nullptr; + (*it)->updateFunction = nullptr; + it = children.erase(it); + } + + if (updateFunction) updateFunction(); +} + Any LuaGuiElement::getAsAny(const std::string& key) const { if (!traits.count(key)) return Any(); auto object = traits.at(key); @@ -167,4 +177,4 @@ Any LuaGuiElement::getAsAny(const std::string& key) const { } throw std::runtime_error("Invalid type requested in getAsAny"); -} +} \ No newline at end of file diff --git a/src/lua/usertype/LuaGuiElement.h b/src/lua/usertype/LuaGuiElement.h index 0e28e663..51b6f706 100644 --- a/src/lua/usertype/LuaGuiElement.h +++ b/src/lua/usertype/LuaGuiElement.h @@ -30,6 +30,8 @@ class LuaGuiElement { void remove(sol::this_state s, sol::object elem); + void clear(sol::this_state s); + std::string type{}, key{}; LuaGuiElement* parent = nullptr; @@ -75,7 +77,8 @@ namespace ClientApi { "get", &LuaGuiElement::get_child, "append", &LuaGuiElement::append, "prepend", &LuaGuiElement::prepend, - "remove", &LuaGuiElement::remove + "remove", &LuaGuiElement::remove, + "clear", &LuaGuiElement::clear ); } } diff --git a/src/lua/usertype/Player.cpp b/src/lua/usertype/Player.cpp index 18b32462..7dd907f5 100644 --- a/src/lua/usertype/Player.cpp +++ b/src/lua/usertype/Player.cpp @@ -16,6 +16,10 @@ unsigned int Api::Usertype::ServerPlayer::get_id() { return player->getId(); } +string Api::Usertype::ServerPlayer::get_username() { + return player->getUsername(); +} + glm::vec3 Api::Usertype::ServerPlayer::get_pos() { return player->getPos(); } @@ -122,6 +126,7 @@ bool Api::Usertype::ServerPlayer::get_flying() { void Api::Usertype::ServerPlayer::bind(State, sol::state& lua, sol::table& core) { lua.new_usertype("Player", "get_id", &ServerPlayer::get_id, + "get_username", &ServerPlayer::get_username, "get_pos", &ServerPlayer::get_pos, "get_block_pos", &ServerPlayer::get_block_pos, "set_pos", &ServerPlayer::set_pos, @@ -180,6 +185,7 @@ void Api::Usertype::LocalPlayer::set_hud(std::shared_ptr hud) { void Api::Usertype::LocalPlayer::bind(State, sol::state& lua, sol::table& core) { lua.new_usertype("Player", "get_id", &LocalPlayer::get_id, + "get_username", &LocalPlayer::get_username, "get_pos", &LocalPlayer::get_pos, "get_block_pos", &LocalPlayer::get_block_pos, "set_pos", &LocalPlayer::set_pos, diff --git a/src/lua/usertype/Player.h b/src/lua/usertype/Player.h index 65ff9dbe..dad4e38e 100644 --- a/src/lua/usertype/Player.h +++ b/src/lua/usertype/Player.h @@ -15,75 +15,80 @@ class LuaGuiElement; namespace Api::Usertype { - class ServerPlayer : public SubgameUsertype { - public: - ServerPlayer(PlayerPtr player) : player(player) {} - - PlayerPtr player; - - unsigned int get_id(); - - glm::vec3 get_pos(); - - glm::vec3 get_block_pos(); - - void set_pos(glm::vec3 pos); - - glm::vec3 get_vel(); - - void set_vel(glm::vec3 vel); - - float get_look_yaw(); - - void set_look_yaw(float rot); - - float get_look_pitch(); - - void set_look_pitch(float rot); - - sol::object get_hand_list(sol::this_state s); - - sol::object get_hand_stack(sol::this_state s); - - void set_hand_list(sol::optional list); - - sol::object get_wield_list(sol::this_state s); - - sol::object get_wield_stack(sol::this_state s); - - void set_wield_list(sol::optional list); - - Inventory get_inventory(); - - Dimension get_dimension(); - - void set_dimension(const std::string& identifier); - - unsigned int get_wield_index(); - - void set_wield_index(unsigned int index); - - void set_flying(bool shouldFly); - - bool get_flying(); - - static void bind(State state, sol::state& lua, sol::table& core); - }; + class ServerPlayer; + class LocalPlayer; +} + +class Api::Usertype::ServerPlayer : public SubgameUsertype { +public: + ServerPlayer(PlayerPtr player) : player(player) {} - class LocalPlayer : public ServerPlayer { - public: - LocalPlayer(PlayerPtr player) : ServerPlayer(player) {} - - bool is_in_menu(); - - void show_menu(std::shared_ptr root); - - void close_menu(); - - std::shared_ptr get_hud(); - - void set_hud(std::shared_ptr hud); - - static void bind(State state, sol::state& lua, sol::table& core); - }; -} \ No newline at end of file + PlayerPtr player; + + unsigned int get_id(); + + string get_username(); + + glm::vec3 get_pos(); + + glm::vec3 get_block_pos(); + + void set_pos(glm::vec3 pos); + + glm::vec3 get_vel(); + + void set_vel(glm::vec3 vel); + + float get_look_yaw(); + + void set_look_yaw(float rot); + + float get_look_pitch(); + + void set_look_pitch(float rot); + + sol::object get_hand_list(sol::this_state s); + + sol::object get_hand_stack(sol::this_state s); + + void set_hand_list(sol::optional list); + + sol::object get_wield_list(sol::this_state s); + + sol::object get_wield_stack(sol::this_state s); + + void set_wield_list(sol::optional list); + + Inventory get_inventory(); + + Dimension get_dimension(); + + void set_dimension(const std::string& identifier); + + unsigned int get_wield_index(); + + void set_wield_index(unsigned int index); + + void set_flying(bool shouldFly); + + bool get_flying(); + + static void bind(State state, sol::state& lua, sol::table& core); +}; + +class Api::Usertype::LocalPlayer : public ServerPlayer { +public: + LocalPlayer(PlayerPtr player) : ServerPlayer(player) {} + + bool is_in_menu(); + + void show_menu(std::shared_ptr root); + + void close_menu(); + + std::shared_ptr get_hud(); + + void set_hud(std::shared_ptr hud); + + static void bind(State state, sol::state& lua, sol::table& core); +}; \ No newline at end of file diff --git a/src/server/Server.cpp b/src/server/Server.cpp index 2dfa3e58..b3d78d52 100644 --- a/src/server/Server.cpp +++ b/src/server/Server.cpp @@ -32,7 +32,7 @@ Server::Server(u16 port, const std::string& subgame) : void Server::update() { const static i64 interval_ns = static_cast((1000 / 60.f) * 1000000L); Timer loop(""); - + world.s()->update(delta); game.s()->update(delta); @@ -58,9 +58,8 @@ void Server::update() { PacketView p(event.packet); auto client = static_cast(event.peer->data); - if (client->player) return playerPacketReceived(p, clients.getClient(client->id)->player); - - if (infoSender.handlePacket(*client, p)) { + if (client->player) playerPacketReceived(p, clients.getClient(client->id)->player); + else if (infoSender.handlePacket(*client, p)) { auto clientShr = clients.getClient(client->id); clients.createPlayer(clientShr, world->getDefaultDimension()); } @@ -93,7 +92,7 @@ void Server::update() { playersUpdated.clear(); - u64 sleep_for = (std::max)(interval_ns - static_cast(loop.elapsedNs()), 0L); + i64 sleep_for = (std::max)(interval_ns - static_cast(loop.elapsedNs()), 0L); if (sleep_for > 0) std::this_thread::sleep_for(std::chrono::nanoseconds(sleep_for)); delta = loop.elapsedNs() / 1000000.f / 1000.f; @@ -164,6 +163,7 @@ void Server::playerPacketReceived(PacketView& p, sptr player) { } case Packet::Type::INV_INTERACT: { + // TODO: When reading these parameters, there's a bad_alloc error. bool primary = p.d.read(); string source = p.d.read(); string list = p.d.read(); @@ -174,9 +174,10 @@ void Server::playerPacketReceived(PacketView& p, sptr player) { case Packet::Type::MOD_MESSAGE: { string source = p.d.read(); - string list = p.d.read(); + string message = p.d.read(); game->getParser().safe_function(game->getParser().core["trigger"], "message", - source, game->getParser().safe_function(game->getParser().core["deserialize"], list)); + source, game->getParser().safe_function(game->getParser().core["deserialize"], message), + Api::Usertype::ServerPlayer(player)); break; } } diff --git a/src/server/stream/ServerGenStream.cpp b/src/server/stream/ServerGenStream.cpp index 4f630dab..9567cac1 100644 --- a/src/server/stream/ServerGenStream.cpp +++ b/src/server/stream/ServerGenStream.cpp @@ -16,7 +16,6 @@ ServerGenStream::ServerGenStream(ServerSubgame& game, ServerWorld& world) : bool ServerGenStream::queue(u16 dimension, ivec3 pos) { auto v4 = ivec4(pos, dimension); -// if (!queuedMap.count(v4)) { if (queuedMap.find(v4) == queuedMap.end() && inProgressMap.find(v4) == inProgressMap.end()) { queuedTasks.push(v4); queuedMap.emplace(v4); @@ -28,6 +27,7 @@ bool ServerGenStream::queue(u16 dimension, ivec3 pos) { uptr> ServerGenStream::update() { auto created = make_unique>(); + usize dequeued = 0; for (usize i = 0; i < THREAD_QUEUE_SIZE; i++) { for (auto& t : threads) { auto& j = t.jobs[i]; @@ -43,6 +43,7 @@ uptr> ServerGenStream::update() { queuedMap.erase(pos); inProgressMap.emplace(pos); queuedTasks.pop(); + dequeued++; j.pos = ivec3(pos); j.gen = world.getDimension(pos.w)->getGen(); @@ -52,6 +53,9 @@ uptr> ServerGenStream::update() { } } + if (dequeued >= THREAD_QUEUE_SIZE * THREADS) + std::cout << Log::err << "Server threads were idle!" << Log::endl; + return created; } diff --git a/src/server/stream/ServerGenStream.h b/src/server/stream/ServerGenStream.h index 0f366843..ef9b5a35 100644 --- a/src/server/stream/ServerGenStream.h +++ b/src/server/stream/ServerGenStream.h @@ -18,7 +18,7 @@ class ServerSubgame; class ServerGenStream { public: static const usize THREADS = 4; - static const usize THREAD_QUEUE_SIZE = 16; + static const usize THREAD_QUEUE_SIZE = 4; struct FinishedJob { FinishedJob(u16 dim, ivec3 pos, uptr created) : @@ -37,13 +37,13 @@ public: std::unique_ptr> update(); - private: +private: struct Job { bool locked = false; uptr created = nullptr; u16 dim; - ivec3 pos{}; + ivec3 pos {}; sptr gen; }; diff --git a/src/util/Bounds.cpp b/src/util/Bounds.cpp index adae3408..7ecc9f8c 100644 --- a/src/util/Bounds.cpp +++ b/src/util/Bounds.cpp @@ -54,6 +54,6 @@ void Bounds::setB(glm::vec3 vecB) { bool Bounds::intersects(glm::vec3 test) { return (test.x >= a.x && test.x <= b.x - && test.y >= a.y && test.y <= b.y - && test.z >= a.z && test.z <= b.z); + && test.y >= a.y && test.y <= b.y + && test.z >= a.z && test.z <= b.z); } diff --git a/src/util/Util.h b/src/util/Util.h index 8d071f28..0cca4976 100644 --- a/src/util/Util.h +++ b/src/util/Util.h @@ -38,8 +38,9 @@ namespace Util { return toFixed(val); } - template && - std::is_same_v, V>, bool> = true> + template + || std::is_same_v) + && std::is_same_v, V>, bool> = true> static string toString(V vec) { std::ostringstream out; out << "[ "; @@ -48,8 +49,9 @@ namespace Util { return out.str(); } - template && - std::is_same_v, A>, bool> = true> + template + || std::is_same_v) + && std::is_same_v, A>, bool> = true> static string toString(A arr) { std::ostringstream out; for (usize i = 0; i < arr.size(); i++) out << (i == 0 ? "" : ", ") << arr[i]; @@ -122,7 +124,7 @@ namespace Util { color.g = intFromHexSegment(g) / 255.f; color.b = intFromHexSegment(b) / 255.f; color.a = intFromHexSegment(a) / 255.f; - + return color; } diff --git a/src/world/ServerWorld.cpp b/src/world/ServerWorld.cpp index 012ed160..4eb99910 100644 --- a/src/world/ServerWorld.cpp +++ b/src/world/ServerWorld.cpp @@ -66,23 +66,29 @@ void ServerWorld::update(f64 delta) { refs->update(); u32 genCount = 0; - std::unordered_set updatedChunks {}; auto finishedGen = genStream->update(); + std::unordered_set chunksDirtied {}; Timer t("Finishing Generation"); for (auto& data : *finishedGen) { let dim = getDimension(data.dim); + for (const auto& chunkPair : *data.created) { - updatedChunks.insert(ivec4(chunkPair.first, data.dim)); dim->setChunk(chunkPair.second); + let chunkMapBlockPos = Space::MapBlock::world::fromChunk(chunkPair.first); + if (chunkMapBlockPos != data.pos) { + let chunkMapBlock = dim->getMapBlock(chunkMapBlockPos); + if (chunkMapBlock->generated) chunksDirtied.insert(ivec4(chunkPair.first, data.dim)); + } } - auto mapBlock = dim->getMapBlock(ivec3(data.pos)); + + let mapBlock = dim->getMapBlock(ivec3(data.pos)); + assert(mapBlock); if (!mapBlock->generated) { mapBlock->generated = true; - assert(mapBlock); Serializer s {}; for (u16 i = 0; i < 64; i++) { @@ -102,50 +108,32 @@ void ServerWorld::update(f64 delta) { totalGens++; } } - if (!finishedGen->empty()) { - t.printElapsedMs(); - std::cout << totalGens << std::endl; - } - -// auto finishedPackets = packetStream->update(); -// if (finishedPackets->size()) std::cout << finishedPackets->size() << " finished packets" << std::endl; -// for (auto& data : *finishedPackets) { -// for (auto& client : clients.getClients()) { -// if (!client.second->player) continue; -// data->packet->sendTo(client.second->peer, Packet::Channel::WORLD); -// } -// } generatedMapBlocks = genCount; -// for (auto& chunkPos : updatedChunks) { -// std::cout << Util::toString(chunkPos) << std::endl; -// ivec3 mapBlockPos = Space::MapBlock::world::fromChunk(chunkPos); -// auto dim = getDimension(chunkPos.w); -// auto chunk = dim->getChunk(ivec3(chunkPos)); -// -// assert(chunk != nullptr); -// -//// bool sentAlready = false; -//// for (auto& mapBlock : generatedMapBlocks) if (mapBlock == mapBlockPos) { sentAlready = true; break; } -//// if (sentAlready) continue; -// -// Packet p(Packet::Type::CHUNK); -// p.data = chunk->compress(); -// -// for (auto& client : clients.getClients()) { -// if (!client.second->player) continue; -// + for (auto& chunkPos : chunksDirtied) { + ivec3 mapBlockPos = Space::MapBlock::world::fromChunk(chunkPos); + auto dim = getDimension(chunkPos.w); + auto chunk = dim->getChunk(ivec3(chunkPos)); + assert(chunk); + + Packet p(Packet::Type::CHUNK); + p.data = chunk->compressToString(); + + for (auto& client : clients.getClients()) { + if (!client.second->player) continue; +// std::cout << "dirtied" << chunk->getPos() << std::endl; + // auto myChunk = Space::Chunk::world::fromBlock(client.second->player->getPos()); -// + // std::pair bounds = { // {myChunk.x - activeChunkRange.x, myChunk.y - activeChunkRange.y, myChunk.z - activeChunkRange.x}, // {myChunk.x + activeChunkRange.x, myChunk.y + activeChunkRange.y, myChunk.z + activeChunkRange.x}}; -// -//// if (isInBounds(chunkPos, bounds)) -// p.sendTo(client.second->peer, Packet::Channel::WORLD); -// } -// } + +// if (isInBounds(chunkPos, bounds)) + p.sendTo(client.second->peer, Packet::Channel::WORLD); + } + } Packet r = Serializer().append(generatedMapBlocks).packet(Packet::Type::SERVER_INFO); @@ -178,7 +166,6 @@ void ServerWorld::update(f64 delta) { } // Update clients with removed entities. - Serializer rem; rem.append(ind); for (i64 entity : dimension->getRemovedEntities()) rem.append(entity); @@ -240,32 +227,29 @@ void ServerWorld::sendChunksToPlayer(ServerPlayer& client) { ivec3 playerPos = Space::MapBlock::world::fromBlock(client.getPos()); ivec3 lastPlayerPos = Space::MapBlock::world::fromBlock(client.lastPos); - Bounds newBounds = { playerPos - ivec3{ sendRange.x, sendRange.y, sendRange.x }, - playerPos + ivec3{ sendRange.x, sendRange.y, sendRange.x }}; - Bounds oldBounds = { lastPlayerPos - ivec3{ sendRange.x, sendRange.y, sendRange.x }, - lastPlayerPos + ivec3{ sendRange.x, sendRange.y, sendRange.x }}; + Bounds newBounds = { playerPos - ivec3 { sendRange.x, sendRange.y, sendRange.x }, + playerPos + ivec3 { sendRange.x, sendRange.y, sendRange.x }}; + Bounds oldBounds = { lastPlayerPos - ivec3 { sendRange.x, sendRange.y, sendRange.x }, + lastPlayerPos + ivec3 { sendRange.x, sendRange.y, sendRange.x }}; for (auto& pos : generateOrder) { if (oldBounds.intersects(playerPos + pos) || !newBounds.intersects(playerPos + pos)) continue; -// packetStream->queue(client.getDim()->getInd(), pos + playerPos); -// auto dim = client.getDim(); -// std::cout << dim->getInd() << std::endl; -// auto mb = dim->getMapBlock(pos); -// std::cout << mb << std::endl; -// if (!mb) return; -// Serializer s {}; -// for (u16 i = 0; i < 64; i++) { -// auto chunk = mb->get(i); -// if (chunk) s.append(chunk->compressToString()); -// } -// -// let packet = make_unique(Packet::Type::MAPBLOCK); -// -// for (auto& client : clients.getClients()) { -// if (!client.second->player) continue; -// packet->sendTo(client.second->peer, Packet::Channel::WORLD); -// } + auto dim = client.getDim(); + auto mb = dim->getMapBlock(playerPos + pos); + if (!mb) return; +// std::cout << "sending " << pos << " to " << client.getId() << std::endl; + Serializer s {}; + for (u16 i = 0; i < 64; i++) { + auto chunk = mb->get(i); + if (chunk) s.append(chunk->compressToString()); + } + let packet = s.packet(Packet::Type::MAPBLOCK); + + for (auto& client : clients.getClients()) { + if (!client.second->player) continue; + packet.sendTo(client.second->peer, Packet::Channel::WORLD); + } } } diff --git a/src/world/dim/LocalDimension.cpp b/src/world/dim/LocalDimension.cpp index 3c64d45e..a8d50295 100644 --- a/src/world/dim/LocalDimension.cpp +++ b/src/world/dim/LocalDimension.cpp @@ -83,6 +83,13 @@ void LocalDimension::update(f64 delta) { } void LocalDimension::setChunk(sptr chunk) { + let clientMapBlock = Space::MapBlock::world::fromBlock(static_cast(world).getPlayer()->getPos()); + let mapBlockPos = Space::MapBlock::world::fromChunk(chunk->getPos()); + + if (abs(clientMapBlock.x - mapBlockPos.x) > retainMapBlockRange.x || + abs(clientMapBlock.y - mapBlockPos.y) > retainMapBlockRange.y || + abs(clientMapBlock.z - mapBlockPos.z) > retainMapBlockRange.x) return; + Dimension::setChunk(chunk); meshChunk(chunk); } diff --git a/src/world/dim/ServerDimension.h b/src/world/dim/ServerDimension.h index 9dd7af0e..1dc6e615 100644 --- a/src/world/dim/ServerDimension.h +++ b/src/world/dim/ServerDimension.h @@ -53,7 +53,7 @@ private: std::list luaEntities{}; std::list removedEntities{}; - const ivec2 retainMapBlockRange = { 4, 4 }; + const ivec2 retainMapBlockRange = { 6, 6 }; i64 entityInd = 1; }; diff --git a/src/world/dim/chunk/Chunk.cpp b/src/world/dim/chunk/Chunk.cpp index 2e7a0eb0..f62f5efa 100644 --- a/src/world/dim/chunk/Chunk.cpp +++ b/src/world/dim/chunk/Chunk.cpp @@ -65,7 +65,6 @@ void Chunk::combineWith(sptr o) { generationState = GenerationState::GENERATED; countRenderableBlocks(); } - else generationState = GenerationState::PARTIAL; } diff --git a/src/world/dim/ent/DrawableEntity.cpp b/src/world/dim/ent/DrawableEntity.cpp index 48f9f642..a66adc32 100644 --- a/src/world/dim/ent/DrawableEntity.cpp +++ b/src/world/dim/ent/DrawableEntity.cpp @@ -95,7 +95,6 @@ void DrawableEntity::interpScale(float scale) { void DrawableEntity::setScale(glm::vec3 scale) { visualScale = scale; Entity::setScale(scale); - } void DrawableEntity::interpScale(glm::vec3 scale) { diff --git a/src/world/dim/ent/LocalLuaEntity.cpp b/src/world/dim/ent/LocalLuaEntity.cpp index 3a5f6237..9b80781c 100644 --- a/src/world/dim/ent/LocalLuaEntity.cpp +++ b/src/world/dim/ent/LocalLuaEntity.cpp @@ -12,7 +12,21 @@ LocalLuaEntity::LocalLuaEntity(SubgamePtr game, DimensionPtr dim) : LuaEntity(game, dim), DrawableEntity(game, dim), Entity(game, dim) {} -void LocalLuaEntity::setAppearance(const std::string& mode, const std::string& argA, const std::string& argB) { +void LocalLuaEntity::setScale(f32 newScale) { + if (appearance == "wireframe") model->fromMesh( + WireframeEntity::createMesh({ {}, vec3(newScale) }, 0.035, wfStroke, wfFill)); + else DrawableEntity::setScale(scale); +} + +void LocalLuaEntity::setScale(vec3 newScale) { + if (appearance == "wireframe") model->fromMesh( + WireframeEntity::createMesh({ {}, newScale }, 0.035, wfStroke, wfFill)); + else DrawableEntity::setScale(scale); +} + +void LocalLuaEntity::setAppearance(const string& mode, const string& argA, const string& argB) { + this->appearance = mode; + if (mode == "gameobject" && (argA == "block" || argA == "craftitem")) { ItemDef& def = getGame()->getDefs().fromStr(argB); setModel(def.entityModel); @@ -22,5 +36,12 @@ void LocalLuaEntity::setAppearance(const std::string& mode, const std::string& a model->fromSerialized(getGame().l()->models.models[argA], { getGame().l()->textures[argB] }); setModel(model); } + else if (mode == "wireframe") { + wfStroke = Util::hexToColorVec(argA); + wfFill = argB.empty() ? vec4() : Util::hexToColorVec(argB); + auto model = std::make_shared(); + model->fromMesh(WireframeEntity::createMesh({ {}, scale }, 0.035, wfStroke, wfFill)); + setModel(model); + } else throw std::runtime_error("Invalid appearance arguments specified."); -} \ No newline at end of file +} diff --git a/src/world/dim/ent/LocalLuaEntity.h b/src/world/dim/ent/LocalLuaEntity.h index c975ab8f..091e3d9f 100644 --- a/src/world/dim/ent/LocalLuaEntity.h +++ b/src/world/dim/ent/LocalLuaEntity.h @@ -11,5 +11,14 @@ class LocalLuaEntity : public virtual DrawableEntity, public LuaEntity { public: LocalLuaEntity(SubgamePtr game, DimensionPtr dim); + virtual void setScale(float newScale) override; + + virtual void setScale(vec3 newScale) override; + virtual void setAppearance(const std::string& dMode, const std::string& argA, const std::string& argB) override; + +protected: + string appearance; + vec3 wfStroke; + vec4 wfFill; }; diff --git a/src/world/gen/MapGen.cpp b/src/world/gen/MapGen.cpp index 20c823bb..bd2e0d42 100644 --- a/src/world/gen/MapGen.cpp +++ b/src/world/gen/MapGen.cpp @@ -35,7 +35,8 @@ MapGen::MapGen(Subgame& game, World& world, u32 seed, std::unordered_set let biomeFractal = FastNoise::New(); biomeFractal->SetSource(biomeScale); - biomeFractal->SetOctaveCount(4); + biomeFractal->SetOctaveCount(5); + biomeFractal->SetLacunarity(3); biomeGenerator = biomeFractal; } diff --git a/src/world/gen/NoiseSample.cpp b/src/world/gen/NoiseSample.cpp index e47aea95..7a0c5cb9 100644 --- a/src/world/gen/NoiseSample.cpp +++ b/src/world/gen/NoiseSample.cpp @@ -3,8 +3,8 @@ #include "NoiseSample.h" - -NoiseSample::NoiseSample(u16vec2 size, u16 precision) : NoiseSample({ size.x, 0, size.y }, precision) {} +NoiseSample::NoiseSample(u16vec2 size, u16 precision): + NoiseSample({ size.x, 0, size.y }, precision) {} NoiseSample::NoiseSample(u16vec3 size, u16 precision): size(size), precision(precision), data((size.x + 1) * (size.y + 1) * (size.z + 1), 0) { @@ -23,7 +23,7 @@ void NoiseSample::generate(ivec3 pos, const FastNoise::SmartNode<>& generator) { interpolateData(); } -void NoiseSample::fill(const NoiseSample::fill_function& fill) { +void NoiseSample::fill(const std::function& fill) { u16vec3 pos {}; for (pos.x = 0; pos.x < size.x + 1; pos.x += precision) for (pos.y = 0; pos.y < size.y + 1; pos.y += precision) @@ -41,8 +41,8 @@ void NoiseSample::interpolateData() { if (pos.x % precision == 0 && pos.y % precision == 0 && pos.z % precision == 0) continue; vec3 frac = vec3(pos) / static_cast(precision); - u16vec3 a = u16vec3(glm::floor(frac)) * static_cast(precision); - u16vec3 b = u16vec3(glm::ceil(frac)) * static_cast(precision); + u16vec3 a = u16vec3(glm::floor(frac)) * precision; + u16vec3 b = u16vec3(glm::ceil(frac)) * precision; vec3 factor = frac - glm::floor(frac); data[index(pos)] = Interp::trilerp( diff --git a/src/world/gen/NoiseSample.h b/src/world/gen/NoiseSample.h index a9fd233f..21534b95 100644 --- a/src/world/gen/NoiseSample.h +++ b/src/world/gen/NoiseSample.h @@ -6,67 +6,49 @@ #include "util/Types.h" #include "util/Interp.h" +/** + * Stores a 2d or 3d array of noise data that can be accessed by local position or index. + * Noise will only be sampled every `precision` blocks, and interpolated between them. + * Generates 1 block larger on each access due to interpolation, but the index signature + * will access it as though it was exactly `size` blocks wide. + */ + class NoiseSample { public: - typedef std::function fill_function; - NoiseSample(u16vec2 size, u16 precision); NoiseSample(u16vec3 size, u16 precision); + /** Populates the data with a noise generator. */ void generate(ivec3 pos, const FastNoise::SmartNode<>& generator); - void fill(const fill_function& fill); + /** Populates the data with a fill function. */ + void fill(const std::function& fill); + /** Retrieves the value from a local position. */ inline f32 operator[](u16vec3 pos) { return data[index(pos)]; } + /** Retrieves the value from an index into a `size`-sized cuboid. */ inline f32 operator[](u32 ind) { return data[shiftIndexByOne(ind)]; } -// inline f32 get(vec3 pos) { -// vec3 scaled = pos * vec3(precision) / scaleBy; -// -// ivec3 a = { scaled.x, scaled.y, scaled.z }; -// vec3 factor = { scaled.x - a.x, scaled.y - a.y, scaled.z - a.z }; -// ivec3 b = { -// (std::min)(static_cast(std::ceil(scaled.x)), precision.x), -// (std::min)(static_cast(std::ceil(scaled.y)), precision.y), -// (std::min)(static_cast(std::ceil(scaled.z)), precision.z) }; -// -// assert(index(b.x, b.y, b.z) < data.size()); -// -// // No vertical interpolation -// if (precision.y == 0) -// return Interp::bilerp( -// data[index(a.x, a.y, a.z)], data[index(b.x, a.y, a.z)], -// data[index(a.x, a.y, b.z)], data[index(b.x, a.y, b.z)], -// factor.x, factor.z); -// -// return Interp::trilerp( -// data[index(a.x, a.y, a.z)], data[index(b.x, a.y, a.z)], -// data[index(a.x, a.y, b.z)], data[index(b.x, a.y, b.z)], -// data[index(a.x, b.y, a.z)], data[index(b.x, b.y, a.z)], -// data[index(a.x, b.y, b.z)], data[index(b.x, b.y, b.z)], -// factor.x, factor.z, factor.y); -// } - private: + /** Interpolates the data between sampled points. */ void interpolateData(); -// inline u32 innerIndex(u16 x, u16 y, u16 z) { -// return static_cast(x) * size.x * size.y + y * size.x + z; -// }; - + /** Retrieves the index for a position vector. */ inline u32 index(u16vec3 pos) { return index(pos.x, pos.y, pos.z); }; + /** Retrieves the index for the inner data from position coordinates. */ inline u32 index(u16 x, u16 y, u16 z) { return static_cast(x) * (size.x + 1) * (size.y + 1) + y * (size.x + 1) + z; }; + /** Shifts an index value from the provided `size` to the internal dimensions. */ inline u32 shiftIndexByOne(u32 ind) { u16vec3 vec = {}; @@ -80,8 +62,13 @@ private: return index(vec); }; + /** The specified size of the Sample. The actual size is 1 larger on each axis. */ u16vec3 size; + + /** The precision at which points are sampled. */ u16 precision; + + /** The point data. */ vec data {}; }; diff --git a/src/world/player/LocalPlayer.cpp b/src/world/player/LocalPlayer.cpp index 57cc4f47..c5fc081e 100644 --- a/src/world/player/LocalPlayer.cpp +++ b/src/world/player/LocalPlayer.cpp @@ -47,6 +47,10 @@ void LocalPlayer::update(Input& input, f64 delta, vec2 mouseDelta) { if (!gameGui.isInMenu()) updateInteract(input, delta); } +string LocalPlayer::getUsername() { + return "UNIMPLEMENTED"; +} + void LocalPlayer::setPos(vec3 pos, bool assert) { Player::setPos(pos, assert); renderer.camera.setPos(pos + getLookOffset()); @@ -447,4 +451,4 @@ void LocalPlayer::updateInteract(Input& input, f64 delta) { dim->wieldItemUse(target, static_cast(dim->getWorld()).getPlayer()); } } -} \ No newline at end of file +} diff --git a/src/world/player/LocalPlayer.h b/src/world/player/LocalPlayer.h index 0f2ed2bf..9b581719 100644 --- a/src/world/player/LocalPlayer.h +++ b/src/world/player/LocalPlayer.h @@ -47,6 +47,8 @@ public: void update(Input& input, f64 delta, vec2 mouseDelta); + virtual string getUsername() override; + /** The following setters call Player setters, but updates some rendering-related information. */ virtual void setPos(vec3 pos, bool assert = false) override; diff --git a/src/world/player/Player.h b/src/world/player/Player.h index dadcf041..ae541ca7 100644 --- a/src/world/player/Player.h +++ b/src/world/player/Player.h @@ -22,6 +22,8 @@ public: this->id = id; } + virtual string getUsername() = 0; + virtual void setDim(DimensionPtr dim, bool assert = false); virtual void setPos(vec3 pos, bool assert = false); diff --git a/src/world/player/ServerPlayer.cpp b/src/world/player/ServerPlayer.cpp index 23716d71..0b4a54fd 100644 --- a/src/world/player/ServerPlayer.cpp +++ b/src/world/player/ServerPlayer.cpp @@ -14,6 +14,10 @@ ServerPlayer::ServerPlayer(ServerClient& client, World& world, SubgamePtr game, inventory->createList("cursor", 1, 1); } +string ServerPlayer::getUsername() { + return client.username; +} + void ServerPlayer::assertField(Packet packet) { packet.type = Packet::Type::THIS_PLAYER_INFO; packet.sendTo(getPeer(), Packet::Channel::INTERACT); @@ -90,4 +94,4 @@ InventoryPtr ServerPlayer::getInventory() { ENetPeer* ServerPlayer::getPeer() { return client.peer; -} \ No newline at end of file +} diff --git a/src/world/player/ServerPlayer.h b/src/world/player/ServerPlayer.h index 126081e1..afa6d495 100644 --- a/src/world/player/ServerPlayer.h +++ b/src/world/player/ServerPlayer.h @@ -23,6 +23,8 @@ class ServerPlayer : public Player { public: ServerPlayer(ServerClient& client, World& world, SubgamePtr game, DimensionPtr dim); + virtual string getUsername() override; + virtual void assertField(Packet packet) override; virtual void handleAssertion(Deserializer& d) override; diff --git a/subgames/zeus/mods/auri_chat/conf.json b/subgames/zeus/mods/auri_chat/conf.json new file mode 100644 index 00000000..0be42906 --- /dev/null +++ b/subgames/zeus/mods/auri_chat/conf.json @@ -0,0 +1,5 @@ +{ + "name": "@auri:chat", + "description": "A simple chat interface and API supporting messaging and commands.", + "version": "0.0.1" +} diff --git a/subgames/zeus/mods/auri_chat/script/api.lua b/subgames/zeus/mods/auri_chat/script/api.lua new file mode 100644 index 00000000..383feef8 --- /dev/null +++ b/subgames/zeus/mods/auri_chat/script/api.lua @@ -0,0 +1,8 @@ +-- The global chat object. +_G['chat'] = { + channels = {}, + channel_order = {}, +} + +if zepha.server then runfile(_PATH .. 'api_server') +else runfile(_PATH .. 'api_client') end \ No newline at end of file diff --git a/subgames/zeus/mods/auri_chat/script/api_client.lua b/subgames/zeus/mods/auri_chat/script/api_client.lua new file mode 100644 index 00000000..71a2289e --- /dev/null +++ b/subgames/zeus/mods/auri_chat/script/api_client.lua @@ -0,0 +1,58 @@ +chat.open = false +chat.current_channel = nil +chat._message_persist_time = 5 + +-- Toggles the chat being open and listening for input. +chat.set_open = function(open) + if open == nil then chat.open = not chat.open + else chat.open = open end + chat._refresh() +end + +-- Sends a message from the player to the chat channel. +chat.send = function(message) + chat.send_channel(nil, message) +end + +-- Sends a message from player to the channel provided. +chat.send_channel = function(channel_name, message) + zepha.send_message('@auri:chat:message', { + channel = channel_name, + content = message + }) +end + +local function add_channel(channel) + print(channel.identifier) + chat.channels[channel.identifier] = { + name = channel.name, + icon = channel.icon, + history = {}, + _current_history_head = 1 + } + + chat.channel_order = channel.order + if chat.current_channel == nil then chat.current_channel = channel.identifier end + chat._refresh() +end + +local function add_message(message) + local channel = chat.channels[message.channel] + if not channel then return end + + table.insert(channel.history, { + from = message.from, + content = message.content, + time = zepha.time.s() + }) + + chat._refresh() + zepha.after(chat._refresh, chat._message_persist_time) +end + +zepha.bind('message', function(channel, message) + if not channel:starts_with('@auri:chat') then return end + + if channel == '@auri:chat:new_channel' then add_channel(message) end + if channel == '@auri:chat:message' then add_message(message) end +end) \ No newline at end of file diff --git a/subgames/zeus/mods/auri_chat/script/api_server.lua b/subgames/zeus/mods/auri_chat/script/api_server.lua new file mode 100644 index 00000000..9318c38f --- /dev/null +++ b/subgames/zeus/mods/auri_chat/script/api_server.lua @@ -0,0 +1,63 @@ +-- Creates a new chat channel with the name and options provided. +chat.create_channel = function(identifier, options) + chat.channels[identifier] = { + name = options.name or identifier, + icon = options.icon, + history = {}, + } + + table.insert(chat.channel_order, identifier) + + zepha.send_message('@auri:chat:new_channel', { + identifier = identifier, + name = options.name or identifier, + icon = options.icon, + order = chat.channel_order + }) +end + +-- Sends a message from the sender specified to the chat channel. +chat.send = function(sender, message) + chat.send_channel(sender, nil, message) +end + +-- Sends a message from the sender specified to the channel provided. +chat.send_channel = function(sender, channel_name, message) + if not channel_name then channel_name = 'chat' end + local channel = chat.channels[channel_name] + if not channel then return end + + table.insert(channel.history, { + from = sender, + content = message, + time = zepha.time.s() + }) + + zepha.send_message('@auri:chat:message', { + channel = channel_name, + from = sender, + content = message + }) +end + +zepha.bind('player_join', function(player) + for _, identifier in ipairs(chat.channel_order) do + local channel = chat.channels[identifier] + zepha.send_message('@auri:chat:new_channel', { + identifier = identifier, + name = channel.name or identifier, + icon = channel.icon, + order = chat.channel_order + }) + end +end) + +zepha.bind('message', function(channel, message, player) + if not channel:starts_with('@auri:chat') then return end + + if channel == '@auri:chat:message' then + local user = player:get_username() + local color = user:sub(16, 16) + chat.send_channel('`b`c' .. color .. user, message.channel, message.content) + end +end) \ No newline at end of file diff --git a/subgames/zeus/mods/auri_chat/script/category_icon.xcf b/subgames/zeus/mods/auri_chat/script/category_icon.xcf new file mode 100644 index 0000000000000000000000000000000000000000..ebea6994c3797a147b5245bef93bb9ff270f76a9 GIT binary patch literal 952 zcmb_aJ5Iwu6m;T%ArJ`vhGO|D6p`W+AVGmBkhp?zY{w+Fk?lazQBy%fMMZ~1&jskY z02iP}qBS$NS1b}GW6i#KpM74xwdV&HVr0AGvSXSWFjcYwdk-#v6*^1c)WL1-frMTL zYv3HXTIwq73it^&JhX1xQ4ly`3SVQB#lzUKQl~4f{In;Ij!#aRY38MVV0lj4i~TNR ztbT4K>3HCXBpUeLy?V>_>}U|hqLrI=?44PnlRxGj(r169O_4uLkCF?^_CrsY9eCqk zUg@-lp`Qvrw0lm%9g*uMPAc+xMHljSG0&`^a;`X1%Gv4&%p6#D-;1MRn13!OM@)j8 zY6fml?_Xmru7z=qWg4U=HbJS^6f5PS#w@01!w+osL{ z*eylNKSO>KQbcuF+80Y- JGaa1Pz5&9lc^m)$ literal 0 HcmV?d00001 diff --git a/subgames/zeus/mods/auri_chat/script/gui.lua b/subgames/zeus/mods/auri_chat/script/gui.lua new file mode 100644 index 00000000..8be99ef1 --- /dev/null +++ b/subgames/zeus/mods/auri_chat/script/gui.lua @@ -0,0 +1,102 @@ +local max_messages = 8 + +local chat_wrap = zepha.build_gui(function() + return Gui.Rect { + position = { 4, '100%' }, + position_anchor = { 0, '200%' }, + size = { 256, 23 + max_messages * 8 }, + + Gui.Rect { + key = 'chat_tabs', + position = { 0, -10 } + }, + + Gui.Rect { + key = 'chat_box', + size = { 256, 2 + max_messages * 8 } + }, + + Gui.Rect { + key = 'chat_input', + size = { 256, 10 }, + position = { 0, 3 + max_messages * 8 } + } + } +end) + +local chat_box = chat_wrap:get('chat_box') +local chat_tabs = chat_wrap:get('chat_tabs') +local chat_input = chat_wrap:get('chat_input') + +-- Rerenders the chat gui. +chat._refresh = function() + chat_box:clear() + chat_tabs:clear() + + if chat.open then + local i = 0 + for _, identifier in ipairs(chat.channel_order) do + local channel = chat.channels[identifier] + chat_tabs:append(function() + return Gui.Rect { + size = { 48, 10 }, + position = { i * 49, 0 }, + background = (chat.current_channel == identifier) and '#0005' or '#0002', + + Gui.Rect { + position = { 2, 2 }, + size = { 8 * (2/3), 8 * (2/3) }, + background = 'multiply(' .. channel.icon .. ', ' .. + (chat.current_channel == identifier and '#ffe791' or '#fff') .. ')' + }, + + Gui.Text { + color = (chat.current_channel == identifier) and '#ffe791' or '#fff', + position = { 8, 2 }, + scale = { 2.02/3, 2.02/3 }, + content = channel.name + } + } + end) + i = i + 1 + end + end + + local channel = chat.channels[chat.current_channel] + if not channel then return end + + local now = zepha.time.s() + local count = 0 + + local start = math.max(chat.open and 1 or channel._current_history_head, #channel.history - max_messages + 1) + + for i = #channel.history, start, -1 do + local message = channel.history[i] + if now - message.time > chat._message_persist_time and not chat.open then + channel._current_history_head = i + 1 + else + chat_box:append(function() + return Gui.Text { + position = { 2, 2 + (max_messages - count - 1) * 8 }, + background = chat.open and '#0000' or '#0003', + scale = { 2.02/3, 2.02/3 }, + content = '`c7[` `r' .. message.from .. '`r` `c7]`cr ' .. message.content .. '`r' + } + end) + count = count + 1 + end + end + + chat_box.background = chat.open and '#0005' or '#0000' + chat_input.background = chat.open and '#0005' or '#0000' +end + +zepha.player:get_hud():append(chat_wrap) +chat._refresh() + +-- Keyboard shortcut to toggle the chat. +zepha.register_keybind(":open_chat", { + description = "Open Chat", + default = zepha.keys.p, + on_press = chat.set_open +}) \ No newline at end of file diff --git a/subgames/zeus/mods/auri_chat/script/init.lua b/subgames/zeus/mods/auri_chat/script/init.lua new file mode 100644 index 00000000..398fd4a0 --- /dev/null +++ b/subgames/zeus/mods/auri_chat/script/init.lua @@ -0,0 +1,8 @@ +runfile(_PATH .. 'api') +if zepha.client then runfile(_PATH .. 'gui') end + +if zepha.server then + chat.create_channel('chat', { name = 'Chat', icon = '@auri:chat:chat_icon' }) +end + +runfile(_PATH .. 'test') \ No newline at end of file diff --git a/subgames/zeus/mods/auri_chat/script/test.lua b/subgames/zeus/mods/auri_chat/script/test.lua new file mode 100644 index 00000000..8038f065 --- /dev/null +++ b/subgames/zeus/mods/auri_chat/script/test.lua @@ -0,0 +1,29 @@ +if zepha.server then + chat.create_channel('commands', { name = 'Commands', icon = '@auri:chat:commands_icon' }) + chat.create_channel('debug', { name = 'Debug', icon = '@auri:chat:debug_icon' }) +-- +-- local random_messages = { +-- { '`b`cbA`cdu`cfr`cdi`cb!', 'the quick brown fox jumps over the lazy dog' }, +-- { '`b`cbA`cdu`cfr`cdi`cb!', 'lorum ipsum dolor sit amet consequitor lorem ipsum dolor sit amet' }, +-- { '`b`cbZ`cay`cet`cch`cdi`c5a', '`iomg shut the fuck up`r' }, +-- { '`b`cbA`cdu`cfr`cdi`cb!', 'lol epic' }, +-- { '`b`cbA`cdu`cfr`cdi`cb!', 'chat mod' }, +-- { '`b`cbZ`cay`cet`cch`cdi`c5a', 'testing testing 123' }, +-- { '`bJAYCEE', 'PENIS!' }, +-- { '`b`cbA`cdu`cfr`cdi`cb!', '#epic' }, +-- { 'alphabet', '`bABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789' } +-- } +-- +-- local function random_message() +-- local message = random_messages[math.floor(math.random() * #random_messages) + 1] +-- chat.send(message[1], message[2]) +-- zepha.after(random_message, math.random() > 0.5 and math.random() * 1 or math.random() * 2) +-- end +-- random_message() +elseif zepha.client then + zepha.register_keybind(":send_test_message", { + description = "Send test message", + default = zepha.keys.j, + on_press = function() chat.send('hihihih') end + }) +end \ No newline at end of file diff --git a/subgames/zeus/mods/auri_chat/textures/chat_icon.png b/subgames/zeus/mods/auri_chat/textures/chat_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4976b92360015d59903677d7f10e3dac9e237029 GIT binary patch literal 525 zcmV+o0`mQdP)EX>4Tx04R~2kg-a`P!xv0RM8@KvN(uCz^(-sGr3fSASlFG!RnMIDHf9$l9b{b z_$K-=9R$HQ@C6i{{cm(|FpC!s|Ht8+|G)P_%TB_yT;7E=s|wd2j4nr4_UapLI&|r= z6NF_x@VpZm&*v+a(U-pQYM%S^tVD4cN*Agu%!>-FeX%pIa>FXRw?qF>{2;cYG>gPf z;$D@CbRIz)7)k~&MwYPU$u?PF{gOgjF~Ydp`tI%)H%XoPwG+-a8F4nO^DT- zYo_8xRLaTaKr|HTHVt`Ob)Kh`u{@^oG6{F2@-%sv|NUP3IIB0U%|#v*LETzXwI&mI ze}v8mHlAVax*@Cm`)v&~PCfI_H+}&Ku~2oZUhI4T0007FOGiWi|A&vvzW@LL32;bR za{vGf6951U69E94oEQKA00(qQO+^Rg2n`e{Br-PgS^xk58FWQhbVF}#ZDnqB07G(R zVRU6=Aa`kWXdp*PO;A^X4i^9b07^+jK~xCWUCgl!fItuf!8t@%lmaEt$2UL;bojwZ zBu4`1g)__R<(FW^S!@B*FxEgkHJG_@6#IKgt-7vNN;9cHk}MG{pAc~aIsz23@BP;& P00000NkvXXu0mjf!%NdO literal 0 HcmV?d00001 diff --git a/subgames/zeus/mods/auri_chat/textures/commands_icon.png b/subgames/zeus/mods/auri_chat/textures/commands_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bd823787b195b70ae69b9369c0042665a8e92506 GIT binary patch literal 541 zcmV+&0^EX>4Tx04R~2kg-a`P!xv0RM8@KvN(uCz^(-sGr3fSASlFG!RnMIDHf9$l9b{b z_$K-=9R$HQ@C6i{{cm(|FpC!s|Ht8+|G)P_%TB_yT;7E=s|wd2j4nr4_UapLI&|r= z6NF_x@VpZm&*v+a(U-pQYM%S^tVD4cN*Agu%!>-FeX%pIa>FXRw?qF>{2;cYG>gPf z;$D@CbRIz)7)k~&MwYPU$u?PF{gOgjF~Ydp`tI%)H%XoPwG+-a8F4nO^DT- zYo_8xRLaTaKr|HTHVt`Ob)Kh`u{@^oG6{F2@-%sv|NUP3IIB0U%|#v*LETzXwI&mI ze}v8mHlAVax*@Cm`)v&~PCfI_H+}&Ku~2oZUhI4T0007FOGiWi|A&vvzW@LL32;bR za{vGf6951U69E94oEQKA00(qQO+^Rg2n`e}06YV92><{98FWQhbVF}#ZDnqB07G(R zVRU6=Aa`kWXdp*PO;A^X4i^9b09r{zK~xCWUCFT#f-nF;(HD;uvQ!vBMzExD3wm2u z2s3%aE=4#REZ`{o<@@{EX>4Tx04R~2kg-a`P!xv0RM8@KvN(uCz^(-sGr3fSASlFG!RnMIDHf9$l9b{b z_$K-=9R$HQ@C6i{{cm(|FpC!s|Ht8+|G)P_%TB_yT;7E=s|wd2j4nr4_UapLI&|r= z6NF_x@VpZm&*v+a(U-pQYM%S^tVD4cN*Agu%!>-FeX%pIa>FXRw?qF>{2;cYG>gPf z;$D@CbRIz)7)k~&MwYPU$u?PF{gOgjF~Ydp`tI%)H%XoPwG+-a8F4nO^DT- zYo_8xRLaTaKr|HTHVt`Ob)Kh`u{@^oG6{F2@-%sv|NUP3IIB0U%|#v*LETzXwI&mI ze}v8mHlAVax*@Cm`)v&~PCfI_H+}&Ku~2oZUhI4T0007FOGiWi0IH26G5`Po32;bR za{vGf6951U69E94oEQKA00(qQO+^Rg2n`e~F8R(#hX4Qo8FWQhbVF}#ZDnqB07G(R zVRU6=Aa`kWXdp*PO;A^X4i^9b0AEQ&K~xCWUCOZyKu{D$;qydk0WpddUa8bt#Uxq< zy)krGG&Z<}gyL6_5U2cd;8&2K4lgA1(CKr)vgHLd&y_+}I4g&^$z+-oWipu}iH|ca kd+#{Tt^no0Nd*Yt0@NfVOlg%bOaK4?07*qoM6N<$f*e}hbN~PV literal 0 HcmV?d00001 diff --git a/subgames/zeus/mods/auri_world_edit/script/init.lua b/subgames/zeus/mods/auri_world_edit/script/init.lua new file mode 100644 index 00000000..d2118d85 --- /dev/null +++ b/subgames/zeus/mods/auri_world_edit/script/init.lua @@ -0,0 +1,48 @@ +local box = nil +local pos1 = nil +local pos2 = nil + +zepha.register_entity('@auri:world_edit:box', { + display = 'wireframe', + display_stroke = '#0e7', + + update_pos = function(self) + if pos2 == nil then + self.object.pos = pos1 + self.object.scale = 1 + else + local min = V(math.min(pos1.x, pos2.x), math.min(pos1.y, pos2.y), math.min(pos1.z, pos2.z)) + local max = V(math.max(pos1.x, pos2.x), math.max(pos1.y, pos2.y), math.max(pos1.z, pos2.z)) + local scale = max - min + 1 + + self.object.pos = min + self.object.scale = scale + end + end +}) + +zepha.register_item(':wand', { + name = 'World Edit Wand', + textures = { '@auri:world_edit:wand' }, + stack = 1, + + on_use_client = function(stack, target, player) + if box == nil then + box = zepha.player.dim:add_entity(V(), '@auri:world_edit:box') + end + + if pos1 == nil or pos2 ~= nil then + pos2 = nil + pos1 = V(target.pos or player.pos):floor() + else + pos2 = V(target.pos or player.pos):floor() + end + + box:update_pos() + end +}) + +zepha.bind('new_player', function(player) + local inv = player:get_inventory():get_list('hot_wheel_1') + inv:add_stack({ '@auri:world_edit:wand', 1 }) +end) diff --git a/subgames/zeus/mods/auri_world_edit/textures/wand.png b/subgames/zeus/mods/auri_world_edit/textures/wand.png new file mode 100644 index 0000000000000000000000000000000000000000..0e864dd721fb24f025cdfa34ada9e25c16f644fb GIT binary patch literal 2451 zcmV;E32gR>P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+Ray6b|k3|{AU%j1SA0x%i(#>?BFhcf`lx)s@-k- zxIb>Di+4(aLK4`G|NT4NKX_Pta3QLtoRY^Aa>!iJFu$L2mE^-!o{qm8Pvh<}!59+M zvb&bf_`o=0J)iM*MF1AEn!(Khx$VYj}3ieCC3ieCHfUdq74LrDBp+D0ksM^aE5 zO2QhyO0-$>Rq|zD??4$KKyp5|9sXg>C)+$&`S@{P+17D~C%PZ4;|A`Ri5E9WUDfoW4V(;h~tH5WxZUY18)ho3q=TWACnnge|ADse32nRtpR3a)Rr# z1bSyMhzGP4_4I74Xm#*0~eW_EYibz zX|jU&4tHQ_a23HQ&*=^py7cBtUn7I&PFTtWVasnmece|U{pp=^#S)P_F+-bRzWkJy z8D*7N21aNeqsGg?_xtRShghU0EL&zaY_RycMbt=dz9kpYf^`w~jxo}{zh8m^bVq<8 z0R=vhL`vk9S&3js13`tnu>`JQfMVnhkQ_u3xIqv=wZk_`*IJIe$B`w$M3f{7ZV;Lv zD})ID(O~eQ5+#NhV~QFr=2()X;1FRcX?1ws~QV2lHS zaa|0obhtS4Mj`NGZgJ)_BPt>TWL(^I@`VxyCt(oBNe}McnEMuQE`>kx#$RR5E$V*A z+{K$4@f~j;u-4bH-7dy<6fT>3LG)pMSYa#c6fN#<{HUH)+-^_brVW^5b-3cp0-##< zTp=05CUWfVXKaPS%e=FnqB*tmpJ;k0dR^DYM&IErT`wDPZ5c*xlD6>zl5stDoUPgK zL_gK;dnSFdC=&kx)nvF9W;yCd1mxEHo^2fmh~CDZA+q0{C=<7bCn+tk`zi4^3b$d* z9QM?JuJLX&bgYvn{Q12Rk27{(k#Nxjq8Z?%EJF|U3g2$uM(92@us@j4jsb`AnkgY9 z9MB%gCDnh5+$ z{^YTaw9dPmUFJjw$-wO(*R8jBZJEN}RtT{5*jwpMD_>IMx`{q&_d4*UTKme7OJS=S zWTm;chBKH(JX2*TE=GEKfd>98?_P%afO^j%9}eWwV?1}PmuJ+Cy%lYepH2U{>D2lC z`IM#w;^B6e?(XwQFs&TZiY<9a z`zUfoeGAe^xOeOz^ec#j?r1g~l=YG9T>f?r`M7o;B%3l$lI09+b&n(S<~BFBf*aO| zcj{%$X{C|BfM(Ud5u~LYR6?WJ!+7sugr|?(UxD-gCP;D9%=Oifw&+&B+A7AfcJj?sspQArtFd5(ziD#K^ zSi~E|)0>vgd7n7K%5t9goOs-z3lcwaU2*x1bID0(wkRN^>s zG_PuuFJxWLbKc^tR_m;NPyWJCL0ehoI?WLzv4|x|5TT%s3aYRWqg5ltM4I*!9{yp+ zFOf?jR|Sk53#dVb?D)a|;CHuXaca^{3MGKv7u)_A1p>Q3t6|&U$F|)%0sPOvmDcgs zn!wB_>5YySJpu-{fs5;ortATiJHX(RE*r8V`DqHpBJh4j-;@Kww?N;T+gp1drw>4e zx=P&u2Zz8|iL%!{-W}}j?cX!){(bh#^4|{iy|c^7A>?<+RzXS zYKcgz8LE)4iz$Q_auMI@oWptE!~32O94cCkODGoxAe0MB?OZhiL%FbIgGu#wO~5xO zu~J!??Iu^guZXLWK{l9F(P~@(0=_}9JC1N0ZYD2QBpXaBt&zcS@u^I^A_^c@Dr1Vt zo40F}^M-O1p{Bj`12Mb?UrJwz_WDU!5f!b*#gW0g*nn7eJNeJTl5TKNIaG^dPXKT^ zf;*bIm)zo|X))W^r8;l*N-f@*9mwv2DF28`-R~F6YG!Kr1K+xAe(o1h{<{DwlnYD3 zil|c&igUxFSv|aZp2GHf@#;F7)kABbm8*}Rk)C-`$JA}c6BBa%V+Nl`r{%nd<<$*z z-Hp3RA(?7ufMaR~7n$|fT Rz~}$~002ovPDHLkV1n5wnvehh literal 0 HcmV?d00001 diff --git a/subgames/zeus/mods/zeus_flowers/textures/pink.png b/subgames/zeus/mods/zeus_flowers/textures/pink.png new file mode 100755 index 0000000000000000000000000000000000000000..a78e9d1f3f6ff999d17e59e87f9c7fd9cde98336 GIT binary patch literal 334 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE({(FNel*myxK*9BAf*t zk;M!Q+`=Ht$S`Y;1W=H@#M9T6{UMLIxVccWYKtaN=(eYeV~EA+INJ#7}`Sj0y+W${K#p{?W-tSBJVdnbo|M~qqJof3D|LSWW zYPU%}m$1FVcIVH5BOe}rNoJG0ThDX;n|(^f=edH;y$cN3>+0|Ir~Il{?s@s&&wtwg z9XaY8Hj{Y%DQ7pa${Ee(oX=>pC#T@sJ=N(F_xAriC@?Ai*oW`u>)X`7?|Wo+z|!r# zz1hdT-g<^LKmT+;Jbu0Y$6P*RhMU}qKhyqudg+MmyY+vgWDDPiwuATW{})!Zr-V<) cWl%I_=rfPBZ#!U72J|L_r>mdKI;Vst03bqz)Bpeg literal 0 HcmV?d00001 diff --git a/subgames/zeus/mods/zeus_inventory/textures/player_frame.png b/subgames/zeus/mods/zeus_inventory/textures/player_frame.png new file mode 100644 index 0000000000000000000000000000000000000000..0495fc629a8e46d2348afb32ba20b5f50060eab0 GIT binary patch literal 7032 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 UOV literal 0 HcmV?d00001 diff --git a/subgames/zeus/mods/zeus_world/script/biomes/desert.lua b/subgames/zeus/mods/zeus_world/script/biomes/desert.lua index eb045dde..59afe444 100644 --- a/subgames/zeus/mods/zeus_world/script/biomes/desert.lua +++ b/subgames/zeus/mods/zeus_world/script/biomes/desert.lua @@ -1,104 +1,105 @@ -local identifier = "zeus:world:desert" - -local structures = {} - -table.insert(structures, zepha.create_structure({ - origin = V(), - probability = 0.001, - layout = {{{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}} -})) - -table.insert(structures, zepha.create_structure({ - origin = V(), - probability = 0.001, - layout = {{{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}} -})) - -table.insert(structures, zepha.create_structure({ - origin = V(), - probability = 0.001, - layout = {{{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}} -})) - -local noise = { --- heightmap = { --- module = "add", --- sources = {{ --- module = "min", --- sources = {{ --- module = "turbulence", --- power = 1, --- frequency = 0.3, +-- local identifier = "zeus:world:desert" +-- +-- local structures = {} +-- +-- table.insert(structures, zepha.create_structure({ +-- origin = V(), +-- probability = 0.001, +-- layout = {{{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}} +-- })) +-- +-- table.insert(structures, zepha.create_structure({ +-- origin = V(), +-- probability = 0.001, +-- layout = {{{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}} +-- })) +-- +-- table.insert(structures, zepha.create_structure({ +-- origin = V(), +-- probability = 0.001, +-- layout = {{{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}} +-- })) +-- +-- local noise = { +-- -- heightmap = runfile(_PATH .. 'world_noise') +-- -- heightmap = { +-- -- module = "add", +-- -- sources = {{ +-- -- module = "min", +-- -- sources = {{ +-- -- module = "turbulence", +-- -- power = 1, +-- -- frequency = 0.3, +-- -- source = { +-- -- module = "add", +-- -- sources = {{ +-- -- -- Elevation +-- -- module = "scale_bias", +-- -- source = { +-- -- module = "spheres", +-- -- frequency = 0.2 +-- -- }, +-- -- scale = 20 +-- -- }, { +-- -- -- Features +-- -- module = "scale_bias", +-- -- source = { +-- -- module = "perlin", +-- -- frequency = 0.1, +-- -- octaves = 6, +-- -- }, +-- -- scale = 8 +-- -- }} +-- -- } +-- -- }, { +-- -- module = "scale_bias", +-- -- scale = 1, +-- -- bias = 1000, +-- -- source = { +-- -- module = "perlin", +-- -- frequency = 0.2 +-- -- } +-- -- }} +-- -- }, { +-- -- module = "const", +-- -- value = -40 +-- -- }} +-- -- } +-- volume = { +-- module = "scale", +-- y_scale = 2, +-- source = { +-- module = "add", +-- scalar = -2200, +-- source = { +-- module = "multiply", +-- scalar = 3000, -- source = { --- module = "add", --- sources = {{ --- -- Elevation --- module = "scale_bias", --- source = { --- module = "spheres", --- frequency = 0.2 --- }, --- scale = 20 --- }, { --- -- Features --- module = "scale_bias", --- source = { --- module = "perlin", --- frequency = 0.1, --- octaves = 6, --- }, --- scale = 8 --- }} +-- module = "simplex", +-- frequency = 0.0025, +-- octaves = 6, +-- lacunarity = 2 -- } --- }, { --- module = "scale_bias", --- scale = 1, --- bias = 1000, --- source = { --- module = "perlin", --- frequency = 0.2 --- } --- }} --- }, { --- module = "const", --- value = -40 --- }} +-- } +-- } -- } - volume = { - module = "scale", - y_scale = 2, - source = { - module = "add", - scalar = -2200, - source = { - module = "multiply", - scalar = 3000, - source = { - module = "simplex", - frequency = 0.0025, - octaves = 6, - lacunarity = 2 - } - } - } - } -} - -zepha.register_biome(identifier, { - environment = { - temperature = 40/100, - humidity = 20/100, - roughness = 10/100 - }, - blocks = { - top = "zeus:default:sand", - soil = "zeus:default:sand", - rock = "zeus:default:sandstone" - }, - tags = { natural = 1, default = 1 }, - biome_tint = "#e6fa61", - noise = noise, - structures = structures -}) - -return identifier; +-- } +-- +-- zepha.register_biome(identifier, { +-- environment = { +-- temperature = 40/100, +-- humidity = 20/100, +-- roughness = 10/100 +-- }, +-- blocks = { +-- top = "zeus:default:sand", +-- soil = "zeus:default:sand", +-- rock = "zeus:default:sandstone" +-- }, +-- tags = { natural = 1, default = 1 }, +-- biome_tint = "#e6fa61", +-- noise = noise, +-- structures = structures +-- }) +-- +-- return identifier; diff --git a/subgames/zeus/mods/zeus_world/script/biomes/plains.lua b/subgames/zeus/mods/zeus_world/script/biomes/plains.lua index 9442f181..bf2a7457 100644 --- a/subgames/zeus/mods/zeus_world/script/biomes/plains.lua +++ b/subgames/zeus/mods/zeus_world/script/biomes/plains.lua @@ -19,26 +19,6 @@ local structures = {} -- layout = {{{ "zeus:flowers:flower_geranium" }}} -- })) -for i = 1, 5 do - table.insert(structures, zepha.create_structure({ - origin = V(), - probability = 0.1, - layout = {{{ "zeus:default:tall_grass_" .. tostring(i) }}} - })) -end --- -table.insert(structures, zepha.create_structure({ - origin = V(), - probability = 0.025, - layout = {{{ "zeus:flowers:flower_geranium" }}} -})) - -table.insert(structures, zepha.create_structure({ - origin = V(), - probability = 0.025, - layout = {{{ "zeus:flowers:flower_white_dandelion" }}} -})) - table.insert(structures, zepha.create_structure({ origin = V(1), probability = 0.025, @@ -141,26 +121,70 @@ table.insert(structures, zepha.create_structure({ } })) +for i = 1, 5 do + table.insert(structures, zepha.create_structure({ + origin = V(), + probability = 0.1, + layout = {{{ "zeus:default:tall_grass_" .. tostring(i) }}} + })) +end +-- +table.insert(structures, zepha.create_structure({ + origin = V(), + probability = 0.025, + layout = {{{ "zeus:flowers:flower_geranium" }}} +})) + +table.insert(structures, zepha.create_structure({ + origin = V(), + probability = 0.025, + layout = {{{ "zeus:flowers:flower_white_dandelion" }}} +})) + local noise = { --- heightmap = runfile(_PATH .. 'world_noise'), - volume = { - module = "scale", - y_scale = 2, - source = { - module = "add", - scalar = -2200, - source = { - module = "multiply", - scalar = 3000, + heightmap = { + module = "add", + sources = { + runfile(_PATH .. 'world_noise'), + { + module = "max", + scalar = 0, source = { - module = "simplex", - frequency = 0.0025, - octaves = 6, - lacunarity = 2 + module = "add", + scalar = -150, + source = { + module = "multiply", + scalar = 400, + source = { + module = "simplex", + frequency = 0.00025, + lacunarity = 2.5, + octaves = 8, + persistence = 0.55 + } + } } } } } +-- volume = { +-- module = "scale", +-- y_scale = 2, +-- source = { +-- module = "add", +-- scalar = -2200, +-- source = { +-- module = "multiply", +-- scalar = 3000, +-- source = { +-- module = "simplex", +-- frequency = 0.0025, +-- octaves = 6, +-- lacunarity = 2 +-- } +-- } +-- } +-- } } zepha.register_biome(identifier, { diff --git a/subgames/zeus/mods/zeus_world/script/biomes/world_noise.lua b/subgames/zeus/mods/zeus_world/script/biomes/world_noise.lua index cb1eb88c..51d370a6 100644 --- a/subgames/zeus/mods/zeus_world/script/biomes/world_noise.lua +++ b/subgames/zeus/mods/zeus_world/script/biomes/world_noise.lua @@ -1,24 +1,11 @@ return { - module = "add", - sources = {{ - -- Elevation - module = "scale_bias", - source = { - module = "perlin", - frequency = 0.002, - octaves = 8 - }, - scale = 250, - bias = -32 - }, { - -- Features - module = "scale_bias", - source = { - module = "perlin", - frequency = 0.2, - octaves = 3, - }, - scale = 6, - bias = 6 - }} + module = "multiply", + scalar = 100, + source = { + module = "simplex", + frequency = 0.0002, + octaves = 5, + lacunarity = 3, + persistence = 0.45 + } }; \ No newline at end of file diff --git a/subgames/zeus/mods/zeus_world/script/init.lua b/subgames/zeus/mods/zeus_world/script/init.lua index 831756cd..49e73745 100644 --- a/subgames/zeus/mods/zeus_world/script/init.lua +++ b/subgames/zeus/mods/zeus_world/script/init.lua @@ -5,8 +5,8 @@ zepha.create_dimension('zeus:world:default', { biomes = { '#natural', '#default' } }) -zepha.create_dimension('zeus:world:endless_desert', { - biomes = { 'zeus:world:desert' } -}) +-- zepha.create_dimension('zeus:world:endless_desert', { +-- biomes = { 'zeus:world:desert' } +-- }) zepha.set_default_dimension('zeus:world:default') \ No newline at end of file