Make Chatbox a menu, update menu api.

master
Auri 2021-08-30 16:59:01 -07:00
parent 921649b17b
commit f19199dbb3
19 changed files with 194 additions and 176 deletions

View File

@ -45,7 +45,8 @@ bool Input::isMouseDown(u32 button) {
void Input::setMouseLocked(bool lock) {
forceMouseUnlocked = !lock;
mouseLocked = lock;
glfwSetCursorPos(window, LOCKED_MOUSE_POS.x, LOCKED_MOUSE_POS.y);
let mousePos = static_cast<Window*>(glfwGetWindowUserPointer(window))->getSize() / 2;
glfwSetCursorPos(window, mousePos.x, mousePos.y);
glfwSetInputMode(window, GLFW_CURSOR, (mouseLocked ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL));
}

View File

@ -34,8 +34,9 @@ class Model {
const ModelAnimation& getAnimation();
std::vector<std::unique_ptr<EntityMesh>> meshes;
private:
std::vector<std::unique_ptr<EntityMesh>> meshes {};
private:
void loadModelMeshes(aiNode* node, const aiScene* scene);
void loadMeshAndBone(aiMesh* mesh, std::unique_ptr<EntityMesh>& target);
@ -73,11 +74,11 @@ class Model {
return merge(keysArray[index].second, keysArray[nextIndex].second, factor);
}
ModelAnimation animation{};
std::vector<ModelBone*> rootBones{};
std::vector<ModelBone> bones{};
std::vector<std::shared_ptr<AtlasRef>> textures{};
ModelAnimation animation {};
std::vector<ModelBone*> rootBones {};
std::vector<ModelBone> bones {};
std::vector<std::shared_ptr<AtlasRef>> textures {};
glm::mat4 globalInverseTransform{};
glm::mat4 globalInverseTransform {};
};

View File

@ -5,13 +5,14 @@
#include "EntityMesh.h"
EntityMesh::EntityMesh(const EntityMesh& o) :
Mesh(),
vertices(o.vertices),
indices(o.indices) {
this->indCount = o.indCount;
if (indCount > 0) initModel();
}
void EntityMesh::create(const std::vector<EntityVertex>& vertices, const std::vector<unsigned int>& indices) {
void EntityMesh::create(const vec<EntityVertex>& vertices, const vec<u32>& indices) {
indCount = static_cast<GLsizei>(indices.size());
this->vertices = vertices;
this->indices = indices;
@ -22,18 +23,18 @@ void EntityMesh::create(const std::vector<EntityVertex>& vertices, const std::ve
void EntityMesh::initModel() {
if (vertices.size() == 0) return;
genArrays(static_cast<unsigned int>(vertices.size() * sizeof(EntityVertex)),
static_cast<unsigned int>(indices.size() * sizeof(unsigned int)),
genArrays(static_cast<u32>(vertices.size() * sizeof(EntityVertex)),
static_cast<u32>(indices.size() * sizeof(u32)),
&vertices.front(), &indices.front());
unsigned int idx = 0;
u32 idx = 0;
createVertexAttrib(idx++, 3, GL_FLOAT, false, STRIDE_OFFSET_ENTITY(position));
createVertexAttrib(idx++, 4, GL_FLOAT, false, STRIDE_OFFSET_ENTITY(colorData));
createVertexAttrib(idx++, 3, GL_FLOAT, false, STRIDE_OFFSET_ENTITY(colorBlend));
createVertexAttrib(idx++, 1, GL_FLOAT, false, STRIDE_OFFSET_ENTITY(useTex));
createVertexAttrib(idx++, 3, GL_FLOAT, false, STRIDE_OFFSET_ENTITY(normal));
createVertexAttrib(idx++, 4, GL_INT, true, STRIDE_OFFSET_ENTITY(boneIDs));
createVertexAttrib(idx, 4, GL_FLOAT, false, STRIDE_OFFSET_ENTITY(boneWeights));
createVertexAttrib(idx++, 4, GL_INT, true, STRIDE_OFFSET_ENTITY(boneIDs));
createVertexAttrib(idx, 4, GL_FLOAT, false, STRIDE_OFFSET_ENTITY(boneWeights));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

View File

@ -1,28 +1,22 @@
//
// Created by aurailus on 18/06/19.
//
#pragma once
#include <vector>
#include "Mesh.h"
#include "EntityVertex.h"
class EntityMesh : public Mesh {
public:
public:
EntityMesh() = default;
EntityMesh(const EntityMesh& o);
void create(const std::vector<EntityVertex>& vertices, const std::vector<unsigned int>& indices);
void create(const vec<EntityVertex>& vertices, const vec<u32>& indices);
~EntityMesh() = default;
private:
private:
void initModel();
std::vector<EntityVertex> vertices{};
std::vector<unsigned int> indices{};
vec<u32> indices {};
vec<EntityVertex> vertices {};
};

View File

@ -1,6 +1,8 @@
#include "Mesh.h"
void Mesh::draw() const {
if (VAO == 0) return;
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);

View File

@ -23,8 +23,10 @@ void Gui::BoxElement::updateElement() {
const let bgColor = getStyle<vec4, Type::COLOR>(bgRule);
const string bgImage = getStyle<string>(bgRule, "");
let mesh = std::make_unique<EntityMesh>();
if (bgColor && bgColor->a != 0) {
if ((!bgColor || bgColor->a == 0) && bgImage.empty()) entity.setModel(nullptr);
else if (bgColor) {
let mesh = make_unique<EntityMesh>();
tex = nullptr;
mesh->create({
{ { 0, 0, 0 }, *bgColor, vec3(1), false, {}, {}, {} },
@ -32,8 +34,14 @@ void Gui::BoxElement::updateElement() {
{ { 1, 1, 0 }, *bgColor, vec3(1), false, {}, {}, {} },
{ { 1, 0, 0 }, *bgColor, vec3(1), false, {}, {}, {} }
}, { 0, 1, 2, 2, 3, 0 });
let model = make_shared<Model>();
model->fromMesh(std::move(mesh));
entity.setModel(model);
}
else if (!bgImage.empty()) {
else {
let mesh = make_unique<EntityMesh>();
tex = root.atlas[bgImage];
mesh->create({
{ { 0, 0, 0 }, { tex->uv.x, tex->uv.y, 0, 1 }, vec3(1), true, {}, {}, {} },
@ -41,11 +49,11 @@ void Gui::BoxElement::updateElement() {
{ { 1, 1, 0 }, { tex->uv.z, tex->uv.w, 0, 1 }, vec3(1), true, {}, {}, {} },
{ { 1, 0, 0 }, { tex->uv.z, tex->uv.y, 0, 1 }, vec3(1), true, {}, {}, {} }
}, { 0, 1, 2, 2, 3, 0 });
let model = make_shared<Model>();
model->fromMesh(std::move(mesh));
entity.setModel(model);
}
let model = make_shared<Model>();
model->fromMesh(std::move(mesh));
entity.setModel(model);
}
let margin = getStyle<vec4, Type::LENGTH>(Prop::MARGIN, {});

View File

@ -163,16 +163,15 @@ void Api::Usertype::ServerPlayer::bind(State, sol::state& lua, sol::table& core)
);
}
bool Api::Usertype::LocalPlayer::is_in_menu() {
return player.l()->isInMenu();
void Api::Usertype::LocalPlayer::set_menu(sol::object elem) {
if (elem.is<sptr<Gui::Element>>()) player.l()->showMenu(elem.as<sptr<Gui::Element>>());
else player.l()->closeMenu();
}
void Api::Usertype::LocalPlayer::show_menu(std::shared_ptr<Gui::Element> root) {
return player.l()->showMenu(root);
}
void Api::Usertype::LocalPlayer::close_menu() {
return player.l()->closeMenu();
sol::object Api::Usertype::LocalPlayer::get_menu(sol::this_state s) {
let menu = player.l()->getMenu();
if (menu) return sol::make_object(s, menu);
else return sol::nil;
}
std::shared_ptr<Gui::Element> Api::Usertype::LocalPlayer::get_hud() {
@ -208,8 +207,8 @@ void Api::Usertype::LocalPlayer::bind(State, sol::state& lua, sol::table& core)
"get_dimension", &LocalPlayer::get_dimension,
"show_menu", &LocalPlayer::show_menu,
"close_menu", &LocalPlayer::close_menu,
"get_menu", &LocalPlayer::get_menu,
"set_menu", &LocalPlayer::set_menu,
"set_hud", &LocalPlayer::set_hud,
"get_hud", &LocalPlayer::get_hud,
@ -222,6 +221,6 @@ void Api::Usertype::LocalPlayer::bind(State, sol::state& lua, sol::table& core)
"flying", sol::property(&LocalPlayer::set_flying, &LocalPlayer::get_flying),
"in_menu", sol::property(&LocalPlayer::is_in_menu)
"menu", sol::property(&LocalPlayer::get_menu, &LocalPlayer::set_menu)
);
}

View File

@ -76,11 +76,9 @@ class Api::Usertype::LocalPlayer : public ServerPlayer {
public:
LocalPlayer(PlayerPtr player) : ServerPlayer(player) {}
bool is_in_menu();
sol::object get_menu(sol::this_state s);
void show_menu(std::shared_ptr<Gui::Element> root);
void close_menu();
void set_menu(sol::object elem);
std::shared_ptr<Gui::Element> get_hud();

View File

@ -8,8 +8,9 @@
#include "client/graph/Model.h"
#include "client/graph/ModelAnimation.h"
AnimationState::AnimationState(Model& source) {
const ModelAnimation& animation = source.getAnimation();
AnimationState::AnimationState(Model* source) {
if (!source) return;
const ModelAnimation& animation = source->getAnimation();
ticksPerSecond = animation.ticksPerSecond;
duration = animation.duration;
range = { 0, duration };

View File

@ -15,7 +15,7 @@ class AnimationState {
public:
AnimationState() = default;
explicit AnimationState(Model& source);
explicit AnimationState(Model* source);
void update(double delta);

View File

@ -13,15 +13,15 @@
DrawableEntity::DrawableEntity(SubgamePtr game, DimensionPtr dim) :
Entity(game, dim),
model(std::make_shared<Model>()) {}
Entity(game, dim) {}
DrawableEntity::DrawableEntity(SubgamePtr game, DimensionPtr dim, std::shared_ptr<Model> model) :
Entity(game, dim),
model(model) {}
Entity(game, dim) {
setModel(model);
}
void DrawableEntity::setModel(std::shared_ptr<Model> model) {
animation = AnimationState(*model);
animation = AnimationState(model.get());
this->model = std::move(model);
animation.setPlaying(true);
}

View File

@ -76,6 +76,6 @@ protected:
glm::vec3 visualScale{ 1, 1, 1 };
std::shared_ptr<Model> model = nullptr;
std::vector<glm::mat4> transforms{};
std::vector<glm::mat4> transforms {};
};

View File

@ -109,6 +109,10 @@ void LocalPlayer::showMenu(sptr<Gui::Element> newMenu) {
renderer.window.input.setMouseLocked(false);
}
sptr<Gui::Element> LocalPlayer::getMenu() {
return menu->get(0);
}
void LocalPlayer::closeMenu() {
menu->clear();
renderer.window.input.setMouseLocked(true);

View File

@ -71,6 +71,9 @@ public:
/** Gets the hud element. */
sptr<Gui::Element> getHud();
/** Gets the menu element. */
sptr<Gui::Element> getMenu();
/** Sets the hud to the specified element. */
void setHud(sptr<Gui::Element> hud);

View File

@ -2,13 +2,6 @@ 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)

View File

@ -57,7 +57,7 @@ zepha.bind('message', function(channel, message, player)
if channel == '@auri:chat:message' then
local user = player:get_username()
local color = user:sub(16, 16)
local color = tonumber(user:sub(16, 16)) + 4
chat.send_channel('`b`c' .. color .. user, message.channel, message.content)
end
end)

View File

@ -1,62 +1,69 @@
local max_messages = 8
local chat_pos = { '4dp', '100ch - 100sh - 4dp - 80dp' }
local chat_size = { '256dp', 23 + max_messages * 8 .. 'dp' }
local chat_wrap = zepha.gui(function()
return Gui.Box {
pos = { 4, '100ch - 100sh - 100dp' },
size = { 256, 23 + max_messages * 8 },
local chat_hud = zepha.Gui.Box {
pos = chat_pos,
size = chat_size,
}
Gui.Box {
id = 'chat_tabs',
pos = { 0, -10 }
},
local chat_menu = zepha.Gui.Box {
pos = chat_pos,
size = chat_size,
Gui.Box {
id = 'chat_box',
size = { 256, 2 + max_messages * 8 }
},
zepha.Gui.Box {
id = 'chat_tabs',
pos = { '0', '-10dp' }
},
Gui.Box {
id = 'chat_input',
size = { 256, 10 },
pos = { 0, 3 + max_messages * 8 }
}
zepha.Gui.Box {
id = 'chat_box',
size = { '256dp', 2 + max_messages * 8 .. 'dp' }
},
zepha.Gui.Box {
id = 'chat_input',
size = { '256dp', '10dp' },
pos = { '0dp', 3 + max_messages * 8 .. 'dp' }
}
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')
local chat_menu_box = chat_menu:get('chat_box')
local chat_menu_tabs = chat_menu:get('chat_tabs')
local chat_menu_input = chat_menu:get('chat_input')
-- Rerenders the chat gui.
chat._refresh = function()
chat_box:clear()
chat_tabs:clear()
chat_hud:clear()
chat_menu_box:clear()
chat_menu_box.background = chat.open and '#0005' or '#0000'
chat_menu_input.background = chat.open and '#0005' or '#0000'
if chat.open then
chat_menu_tabs:clear()
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',
chat_menu_tabs:append(Gui.Box {
size = { '48dp', '10dp' },
pos = { i * 49 .. 'dp', '0dp' },
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') .. ')'
},
zepha.Gui.Box {
pos = '2dp',
size = { '8px * 2', '8px * 2' },
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
}
zepha.Gui.Text {
text_size = '2px',
pos = { '8dp', '2dp' },
content = channel.name,
text_color = (chat.current_channel == identifier) and '#ffe791' or '#fff',
}
end)
})
i = i + 1
end
end
@ -68,31 +75,40 @@ chat._refresh = function()
local count = 0
local start = math.max(chat.open and 1 or channel._current_history_head, #channel.history - max_messages + 1)
local append_to = chat.open and chat_menu_box or chat_hud
append_to:clear()
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)
append_to:append(zepha.Gui.Text {
text_size = '2px',
background = chat.open and '#0000' or '#0003',
pos = { '2dp', 2 + (max_messages - count - 1) * 8 .. 'dp' },
content = '`c1[` `r' .. message.from .. '`r` `c1]`cr ' .. message.content .. '`r'
})
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)
zepha.player:get_hud():append(chat_hud)
chat._refresh()
-- Toggles the chat being open and listening for input.
chat.set_open = function(open)
if zepha.player.menu ~= nil and zepha.player.menu ~= chat_menu then return end
if open == nil then chat.open = not chat.open
else chat.open = open end
zepha.player.menu = chat.open and chat_menu or nil
chat._refresh()
end
-- Keyboard shortcut to toggle the chat.
zepha.register_keybind(":open_chat", {
description = "Open Chat",

View File

@ -1,7 +1,7 @@
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' },

View File

@ -1,135 +1,135 @@
local menu = zepha.gui(function()
return Gui.Box {
background = "#0003",
background = '#0003',
Gui.Box {
id = "inventory",
id = 'inventory',
size = { "342dp", "187dp" },
pos = { "50cw - 50sw", "50ch - 50sh" },
size = { '342dp', '187dp' },
pos = { '50cw - 50sw', '50ch - 50sh' },
Gui.Box {
id = "backpack",
id = 'backpack',
pos = { 1, 0 },
size = { "106dp", "187dp" },
padding = { "19dp", "9dp", "8dp", "9dp" },
size = { '106dp', '187dp' },
padding = { '19dp', '9dp', '8dp', '9dp' },
background = "zeus:inventory:backpack"
background = 'zeus:inventory:backpack'
-- Gui.InventoryList {
-- gap = { 2, 2 },
-- pos = { 0, 0 },
--
-- list = "main",
-- source = "current_player"
-- list = 'main',
-- source = 'current_player'
-- },
-- Gui.InventoryList {
-- gap = { 2, 2 },
-- pos = { 0, 18 * 3 },
--
-- list = "hot_wheel_1",
-- source = "current_player"
-- list = 'hot_wheel_1',
-- source = 'current_player'
-- },
-- Gui.InventoryList {
-- gap = { 2, 2 },
-- pos = { 0, 18 * 4 },
--
-- list = "hot_wheel_2",
-- source = "current_player"
-- list = 'hot_wheel_2',
-- source = 'current_player'
-- },
-- Gui.InventoryList {
-- gap = { 2, 2 },
-- pos = { 0, 18 * 5 },
--
-- list = "hot_wheel_3",
-- source = "current_player"
-- list = 'hot_wheel_3',
-- source = 'current_player'
-- },
-- Gui.InventoryList {
-- gap = { 2, 2 },
-- pos = { 0, 18 * 6 },
--
-- list = "hot_wheel_4",
-- source = "current_player"
-- list = 'hot_wheel_4',
-- source = 'current_player'
-- },
-- Gui.InventoryList {
-- gap = { 2, 2 },
-- pos = { 0, 18 * 7 },
--
-- list = "hot_wheel_5",
-- source = "current_player"
-- list = 'hot_wheel_5',
-- source = 'current_player'
-- },
-- Gui.InventoryList {
-- gap = { 2, 2 },
-- pos = { 0, 18*8 },
--
-- list = "hot_wheel_6",
-- source = "current_player"
-- list = 'hot_wheel_6',
-- source = 'current_player'
-- }
},
Gui.Box {
id = "player_frame",
id = 'player_frame',
pos = { "105dp", 0 },
size = { "106dp", "187dp" },
pos = { '105dp', 0 },
size = { '106dp', '187dp' },
background = "zeus:inventory:player_frame",
background = 'zeus:inventory:player_frame',
-- Gui.Model {
-- pos = { 52, 150 },
-- size = { 64, 64 },
--
-- type = "model",
-- type = 'model',
-- anim_range = { 0, 100 },
-- source = "zeus:default:player",
-- texture = "zeus:default:player"
-- source = 'zeus:default:player',
-- texture = 'zeus:default:player'
-- }
},
Gui.Box {
id = "equipment",
id = 'equipment',
pos = { "209dp", "1dp" },
size = { "132dp", "80dp" },
padding = { "18dp", "8dp", "8dp", "8dp" },
background = "zeus:inventory:equipment",
pos = { '209dp', '1dp' },
size = { '132dp', '80dp' },
padding = { '18dp', '8dp', '8dp', '8dp' },
background = 'zeus:inventory:equipment',
Gui.Box {
id = "player_clamp",
id = 'player_clamp',
pos = { "41dp", "1dp" },
size = { "34dp", "52dp" },
overflow = "hidden"
pos = { '41dp', '1dp' },
size = { '34dp', '52dp' },
overflow = 'hidden'
}
},
Gui.Box {
id = "dynamic",
id = 'dynamic',
pos = { "209dp", "80dp" },
size = { "132dp", "107dp" },
padding = "8dp",
pos = { '209dp', '80dp' },
size = { '132dp', '107dp' },
padding = '8dp',
background = "zeus:inventory:dynamic"
background = 'zeus:inventory:dynamic'
-- Gui.InventoryList {
-- gap = { 2, 2 },
-- pos = { 1, 1 },
--
-- list = "mod",
-- source = "current_player",
-- list = 'mod',
-- source = 'current_player',
-- },
-- Gui.InventoryList {
-- gap = { 2, 2 },
-- pos = { 41, 32 },
--
-- list = "craft",
-- source = "current_player"
-- list = 'craft',
-- source = 'current_player'
-- },
-- Gui.InventoryList {
-- gap = { 2, 2 },
-- pos = { 81, 41 },
--
-- list = "craft_result",
-- source = "current_player"
-- list = 'craft_result',
-- source = 'current_player'
-- }
}
}
@ -137,15 +137,12 @@ local menu = zepha.gui(function()
end)
inventory.open_inventory = function()
if not zepha.player.in_menu then
zepha.player:show_menu(menu)
else
zepha.player:close_menu()
end
if zepha.player.menu ~= nil and zepha.player.menu ~= menu then return end
zepha.player.menu = not zepha.player.menu and menu or nil
end
zepha.register_keybind("zeus:inventory:open_inventory", {
description = "Open Inventory",
zepha.register_keybind('zeus:inventory:open_inventory', {
description = 'Open Inventory',
default = zepha.keys['.'],
on_press = inventory.open_inventory
})
})