fix
This commit is contained in:
commit
ae330a9165
42
.github/workflows/appimage-wayland.yml
vendored
42
.github/workflows/appimage-wayland.yml
vendored
@ -1,42 +0,0 @@
|
||||
name: C/C++ AppImage (wayland)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
|
||||
jobs:
|
||||
build-appimage:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'true'
|
||||
- name: install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential libglfw3-wayland libglfw3-dev libglew-dev libglm-dev libpng-dev libopenal-dev libluajit-5.1-dev cmake squashfs-tools
|
||||
sudo ln -s /usr/lib/x86_64-linux-gnu/libluajit-5.1.a /usr/lib/x86_64-linux-gnu/liblua5.1.a
|
||||
sudo ln -s /usr/include/luajit-2.1 /usr/include/lua
|
||||
- name: configure
|
||||
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DVOXELENGINE_BUILD_APPDIR=1
|
||||
- name: build
|
||||
run: cmake --build build -t install
|
||||
- name: Build AppImage
|
||||
uses: AppImageCrafters/build-appimage-action@fe2205a4d6056be47051f7b1b3811106e9814910
|
||||
env:
|
||||
UPDATE_INFO: gh-releases-zsync|MihailRis|VoxelEngine-Cpp|latest|*x86_64.AppImage.zsync
|
||||
with:
|
||||
recipe: dev/AppImageBuilder.yml
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: AppImage
|
||||
path: './*.AppImage*'
|
||||
@ -1,8 +1,8 @@
|
||||
# Run with compiled executable file:
|
||||
|
||||
[Windows 64 bit](https://github.com/MihailRis/VoxelEngine-Cpp/releases/download/v18/voxelengine_v18_win64.zip)
|
||||
[Windows 64 bit](https://github.com/MihailRis/VoxelEngine-Cpp/releases/download/v19/voxelengine_v19_win64.zip)
|
||||
|
||||
[Linux x86_64 (.AppImage)](https://github.com/MihailRis/VoxelEngine-Cpp/releases/download/v18/VoxelEngine-0.18-x86_64.AppImage)
|
||||
[Linux x86_64 (.AppImage)](https://github.com/MihailRis/VoxelEngine-Cpp/releases/download/v19/VoxelEngine-0.19-x86_64.AppImage)
|
||||
|
||||
|
||||
# Controls:
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<inventory color="#1F1F1FE0">
|
||||
<inventory>
|
||||
<slots-grid pos="0, 164" rows="1" count="10" sharefunc="inventory_share_func"/>
|
||||
<slots-grid rows="3" start-index="10" count="30" sharefunc="inventory_share_func"/>
|
||||
</inventory>
|
||||
|
||||
@ -20,8 +20,10 @@ function parse_path(path)
|
||||
return string.sub(path, 1, index-1), string.sub(path, index+1, -1)
|
||||
end
|
||||
|
||||
package = {
|
||||
loaded={}
|
||||
}
|
||||
local __cached_scripts = {}
|
||||
local __cached_results = {}
|
||||
|
||||
-- Load script with caching
|
||||
--
|
||||
@ -31,38 +33,44 @@ local __cached_results = {}
|
||||
-- nocache - ignore cached script, load anyway
|
||||
function load_script(path, nocache)
|
||||
local packname, filename = parse_path(path)
|
||||
local fullpath = file.resolve(path);
|
||||
|
||||
-- __cached_scripts used in condition because cached result may be nil
|
||||
if not nocache and __cached_scripts[fullpath] ~= nil then
|
||||
return __cached_results[fullpath]
|
||||
if not nocache and __cached_scripts[path] ~= nil then
|
||||
return package.loaded[path]
|
||||
end
|
||||
if not file.isfile(path) then
|
||||
error("script '"..filename.."' not found in '"..packname.."'")
|
||||
end
|
||||
|
||||
local script, err = loadfile(fullpath)
|
||||
local script, err = loadfile(file.resolve(path))
|
||||
if script == nil then
|
||||
error(err)
|
||||
end
|
||||
local result = script()
|
||||
if not nocache then
|
||||
__cached_scripts[fullpath] = script
|
||||
__cached_results[fullpath] = result
|
||||
__cached_scripts[path] = script
|
||||
package.loaded[path] = result
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function __scripts_cleanup()
|
||||
print("cleaning scripts cache")
|
||||
for k, v in pairs(__cached_scripts) do
|
||||
local packname, _ = parse_path(k)
|
||||
if packname ~= "core" then
|
||||
print("unloaded "..k)
|
||||
__cached_scripts[k] = nil
|
||||
package.loaded[k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function require(path)
|
||||
local prefix, file = parse_path(path)
|
||||
return load_script(prefix..":modules/"..file..".lua")
|
||||
end
|
||||
|
||||
function __reset_scripts_cache()
|
||||
__cached_scripts = {}
|
||||
__cached_results = {}
|
||||
end
|
||||
|
||||
function sleep(timesec)
|
||||
local start = time.uptime()
|
||||
while time.uptime() - start < timesec do
|
||||
|
||||
@ -150,6 +150,14 @@ std::wstring Button::getText() const {
|
||||
return L"";
|
||||
}
|
||||
|
||||
glm::vec4 Button::getPressedColor() const {
|
||||
return pressedColor;
|
||||
}
|
||||
|
||||
void Button::setPressedColor(glm::vec4 color) {
|
||||
pressedColor = color;
|
||||
}
|
||||
|
||||
Button* Button::textSupplier(wstringsupplier supplier) {
|
||||
if (label) {
|
||||
label->textSupplier(supplier);
|
||||
@ -402,6 +410,7 @@ TrackBar::TrackBar(double min,
|
||||
step(step),
|
||||
trackWidth(trackWidth) {
|
||||
setColor(glm::vec4(0.f, 0.f, 0.f, 0.4f));
|
||||
setHoverColor(glm::vec4(0.01f, 0.02f, 0.03f, 0.5f));
|
||||
}
|
||||
|
||||
void TrackBar::draw(const GfxContext* pctx, Assets* assets) {
|
||||
@ -444,6 +453,55 @@ void TrackBar::mouseMove(GUI*, int x, int y) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double TrackBar::getValue() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
double TrackBar::getMin() const {
|
||||
return min;
|
||||
}
|
||||
|
||||
double TrackBar::getMax() const {
|
||||
return max;
|
||||
}
|
||||
|
||||
double TrackBar::getStep() const {
|
||||
return step;
|
||||
}
|
||||
|
||||
int TrackBar::getTrackWidth() const {
|
||||
return trackWidth;
|
||||
}
|
||||
|
||||
glm::vec4 TrackBar::getTrackColor() const {
|
||||
return trackColor;
|
||||
}
|
||||
|
||||
void TrackBar::setValue(double x) {
|
||||
value = x;
|
||||
}
|
||||
|
||||
void TrackBar::setMin(double x) {
|
||||
min = x;
|
||||
}
|
||||
|
||||
void TrackBar::setMax(double x) {
|
||||
max = x;
|
||||
}
|
||||
|
||||
void TrackBar::setStep(double x) {
|
||||
step = x;
|
||||
}
|
||||
|
||||
void TrackBar::setTrackWidth(int width) {
|
||||
trackWidth = width;
|
||||
}
|
||||
|
||||
void TrackBar::setTrackColor(glm::vec4 color) {
|
||||
trackColor = color;
|
||||
}
|
||||
|
||||
// ================================ CheckBox ==================================
|
||||
CheckBox::CheckBox(bool checked) : UINode(glm::vec2(), glm::vec2(32.0f)), checked(checked) {
|
||||
setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
||||
|
||||
@ -72,6 +72,9 @@ namespace gui {
|
||||
virtual void setText(std::wstring text);
|
||||
virtual std::wstring getText() const;
|
||||
|
||||
virtual glm::vec4 getPressedColor() const;
|
||||
virtual void setPressedColor(glm::vec4 color);
|
||||
|
||||
virtual Button* textSupplier(wstringsupplier supplier);
|
||||
|
||||
virtual void refresh() override;
|
||||
@ -144,7 +147,6 @@ namespace gui {
|
||||
|
||||
class TrackBar : public UINode {
|
||||
protected:
|
||||
glm::vec4 hoverColor {0.01f, 0.02f, 0.03f, 0.5f};
|
||||
glm::vec4 trackColor {1.0f, 1.0f, 1.0f, 0.4f};
|
||||
doublesupplier supplier = nullptr;
|
||||
doubleconsumer consumer = nullptr;
|
||||
@ -165,6 +167,20 @@ namespace gui {
|
||||
virtual void setConsumer(doubleconsumer consumer);
|
||||
|
||||
virtual void mouseMove(GUI*, int x, int y) override;
|
||||
|
||||
virtual double getValue() const;
|
||||
virtual double getMin() const;
|
||||
virtual double getMax() const;
|
||||
virtual double getStep() const;
|
||||
virtual int getTrackWidth() const;
|
||||
virtual glm::vec4 getTrackColor() const;
|
||||
|
||||
virtual void setValue(double);
|
||||
virtual void setMin(double);
|
||||
virtual void setMax(double);
|
||||
virtual void setStep(double);
|
||||
virtual void setTrackWidth(int);
|
||||
virtual void setTrackColor(glm::vec4);
|
||||
};
|
||||
|
||||
class CheckBox : public UINode {
|
||||
|
||||
@ -32,7 +32,13 @@ static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& no
|
||||
node.setSize(element->attr("size").asVec2());
|
||||
}
|
||||
if (element->has("color")) {
|
||||
node.setColor(element->attr("color").asColor());
|
||||
glm::vec4 color = element->attr("color").asColor();
|
||||
glm::vec4 hoverColor = color;
|
||||
if (element->has("hover-color")) {
|
||||
hoverColor = node.getHoverColor();
|
||||
}
|
||||
node.setColor(color);
|
||||
node.setHoverColor(hoverColor);
|
||||
}
|
||||
if (element->has("margin")) {
|
||||
node.setMargin(element->attr("margin").asVec4());
|
||||
@ -54,6 +60,9 @@ static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& no
|
||||
);
|
||||
node.setPositionFunc(supplier);
|
||||
}
|
||||
if (element->has("hover-color")) {
|
||||
node.setHoverColor(element->attr("hover-color").asColor());
|
||||
}
|
||||
std::string alignName = element->attr("align", "").getText();
|
||||
node.setAlign(align_from_string(alignName, node.getAlign()));
|
||||
}
|
||||
@ -163,9 +172,38 @@ static std::shared_ptr<UINode> readButton(UiXmlReader& reader, xml::xmlelement e
|
||||
if (element->has("text-align")) {
|
||||
button->setTextAlign(align_from_string(element->attr("text-align").getText(), button->getTextAlign()));
|
||||
}
|
||||
if (element->has("pressed-color")) {
|
||||
button->setPressedColor(element->attr("pressed-color").asColor());
|
||||
}
|
||||
return button;
|
||||
}
|
||||
|
||||
static std::shared_ptr<UINode> readCheckBox(UiXmlReader& reader, xml::xmlelement element) {
|
||||
auto text = readAndProcessInnerText(element);
|
||||
bool checked = element->attr("checked", "false").asBool();
|
||||
auto checkbox = std::make_shared<FullCheckBox>(text, glm::vec2(), checked);
|
||||
_readPanel(reader, element, *checkbox);
|
||||
|
||||
if (element->has("consumer")) {
|
||||
auto consumer = scripting::create_bool_consumer(
|
||||
reader.getEnvironment().getId(),
|
||||
element->attr("consumer").getText(),
|
||||
reader.getFilename()+".lua"
|
||||
);
|
||||
checkbox->setConsumer(consumer);
|
||||
}
|
||||
|
||||
if (element->has("supplier")) {
|
||||
auto supplier = scripting::create_bool_supplier(
|
||||
reader.getEnvironment().getId(),
|
||||
element->attr("supplier").getText(),
|
||||
reader.getFilename()+".lua"
|
||||
);
|
||||
checkbox->setSupplier(supplier);
|
||||
}
|
||||
return checkbox;
|
||||
}
|
||||
|
||||
static std::shared_ptr<UINode> readTextBox(UiXmlReader& reader, xml::xmlelement element) {
|
||||
auto placeholder = util::str2wstr_utf8(element->attr("placeholder", "").getText());
|
||||
auto text = readAndProcessInnerText(element);
|
||||
@ -181,6 +219,15 @@ static std::shared_ptr<UINode> readTextBox(UiXmlReader& reader, xml::xmlelement
|
||||
);
|
||||
textbox->setTextConsumer(consumer);
|
||||
}
|
||||
|
||||
if (element->has("supplier")) {
|
||||
auto supplier = scripting::create_wstring_supplier(
|
||||
reader.getEnvironment().getId(),
|
||||
element->attr("consumer").getText(),
|
||||
reader.getFilename()+".lua"
|
||||
);
|
||||
textbox->setTextSupplier(supplier);
|
||||
}
|
||||
return textbox;
|
||||
}
|
||||
|
||||
@ -216,6 +263,9 @@ static std::shared_ptr<UINode> readTrackBar(UiXmlReader& reader, xml::xmlelement
|
||||
);
|
||||
bar->setSupplier(supplier);
|
||||
}
|
||||
if (element->has("track-color")) {
|
||||
bar->setTrackColor(element->attr("track-color").asColor());
|
||||
}
|
||||
return bar;
|
||||
}
|
||||
|
||||
@ -227,6 +277,7 @@ UiXmlReader::UiXmlReader(const scripting::Environment& env, AssetsLoader& assets
|
||||
add("panel", readPanel);
|
||||
add("button", readButton);
|
||||
add("textbox", readTextBox);
|
||||
add("chackbox", readCheckBox);
|
||||
add("trackbar", readTrackBar);
|
||||
add("container", readContainer);
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#include "hud.h"
|
||||
|
||||
// TODO: refactor this garbage
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
@ -27,6 +29,7 @@
|
||||
#include "../window/input.h"
|
||||
#include "../voxels/Chunks.h"
|
||||
#include "../voxels/Block.h"
|
||||
#include "../voxels/Chunk.h"
|
||||
#include "../world/World.h"
|
||||
#include "../world/Level.h"
|
||||
#include "../objects/Player.h"
|
||||
@ -365,11 +368,22 @@ void Hud::update(bool visible) {
|
||||
Events::toggleCursor();
|
||||
}
|
||||
|
||||
if (blockUI) {
|
||||
voxel* vox = level->chunks->get(currentblock.x, currentblock.y, currentblock.z);
|
||||
if (vox == nullptr || vox->id != currentblockid) {
|
||||
closeInventory();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& element : elements) {
|
||||
element.getNode()->setVisible(visible);
|
||||
}
|
||||
|
||||
glm::vec2 invSize = contentAccessPanel->getSize();
|
||||
contentAccessPanel->setVisible(inventoryOpen);
|
||||
contentAccessPanel->setSize(glm::vec2(invSize.x, Window::height));
|
||||
contentAccess->setMinSize(glm::vec2(1, Window::height));
|
||||
// hotbarView->setVisible(visible && !inventoryOpen);
|
||||
hotbarView->setVisible(visible);
|
||||
|
||||
for (int i = keycode::NUM_1; i <= keycode::NUM_9; i++) {
|
||||
if (Events::jpressed(i)) {
|
||||
@ -388,10 +402,12 @@ void Hud::update(bool visible) {
|
||||
player->setChosenSlot(slot);
|
||||
}
|
||||
|
||||
for (auto& element : elements) {
|
||||
element.update(pause, inventoryOpen, player->debug);
|
||||
if (element.isRemoved()) {
|
||||
remove(element);
|
||||
if (visible) {
|
||||
for (auto& element : elements) {
|
||||
element.update(pause, inventoryOpen, player->debug);
|
||||
if (element.isRemoved()) {
|
||||
remove(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
cleanup();
|
||||
@ -431,12 +447,12 @@ void Hud::openInventory(glm::ivec3 block, UiDocument* doc, std::shared_ptr<Inven
|
||||
}
|
||||
openInventory();
|
||||
if (blockinv == nullptr) {
|
||||
Events::toggleCursor();
|
||||
abort();
|
||||
blockinv = level->inventories->createVirtual(blockUI->getSlotsCount());
|
||||
}
|
||||
level->chunks->getChunkByVoxel(block.x, block.y, block.z)->setUnsaved(true);
|
||||
blockUI->bind(blockinv, frontend, interaction.get());
|
||||
currentblock = block;
|
||||
currentblockid = level->chunks->get(block.x, block.y, block.z)->id;
|
||||
add(HudElement(hud_element_mode::inventory_bound, doc, blockUI, false));
|
||||
}
|
||||
|
||||
|
||||
@ -90,6 +90,7 @@ class Hud {
|
||||
std::shared_ptr<InventoryView> inventoryView = nullptr;
|
||||
std::shared_ptr<InventoryView> blockUI = nullptr;
|
||||
glm::ivec3 currentblock {};
|
||||
blockid_t currentblockid = 0;
|
||||
|
||||
std::shared_ptr<gui::UINode> createDebugPanel(Engine* engine);
|
||||
std::shared_ptr<InventoryView> createContentAccess();
|
||||
|
||||
@ -102,13 +102,9 @@ void BlocksRenderer::face(const vec3& coord,
|
||||
void BlocksRenderer::vertex(const vec3& coord,
|
||||
float u, float v,
|
||||
const vec4& tint,
|
||||
const vec3& X,
|
||||
const vec3& Y,
|
||||
const vec3& Z) {
|
||||
// TODO: optimize
|
||||
vec3 axisX = glm::normalize(X);
|
||||
vec3 axisY = glm::normalize(Y);
|
||||
vec3 axisZ = glm::normalize(Z);
|
||||
const vec3& axisX,
|
||||
const vec3& axisY,
|
||||
const vec3& axisZ) {
|
||||
vec3 pos = coord+axisZ*0.5f+(axisX+axisY)*0.5f;
|
||||
vec4 light = pickSoftLight(ivec3(round(pos.x), round(pos.y), round(pos.z)), axisX, axisY);
|
||||
vertex(coord, u, v, light * tint);
|
||||
@ -130,11 +126,15 @@ void BlocksRenderer::face(const vec3& coord,
|
||||
float d = glm::dot(Z, SUN_VECTOR);
|
||||
d = 0.8f + d * 0.2f;
|
||||
|
||||
vec3 axisX = glm::normalize(X);
|
||||
vec3 axisY = glm::normalize(Y);
|
||||
vec3 axisZ = glm::normalize(Z);
|
||||
|
||||
vec4 tint(d);
|
||||
vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, tint, X, Y, Z);
|
||||
vertex(coord + ( X - Y + Z) * s, region.u2, region.v1, tint, X, Y, Z);
|
||||
vertex(coord + ( X + Y + Z) * s, region.u2, region.v2, tint, X, Y, Z);
|
||||
vertex(coord + (-X + Y + Z) * s, region.u1, region.v2, tint, X, Y, Z);
|
||||
vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, tint, axisX, axisY, axisZ);
|
||||
vertex(coord + ( X - Y + Z) * s, region.u2, region.v1, tint, axisX, axisY, axisZ);
|
||||
vertex(coord + ( X + Y + Z) * s, region.u2, region.v2, tint, axisX, axisY, axisZ);
|
||||
vertex(coord + (-X + Y + Z) * s, region.u1, region.v2, tint, axisX, axisY, axisZ);
|
||||
} else {
|
||||
vec4 tint(1.0f);
|
||||
vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, tint);
|
||||
@ -142,7 +142,7 @@ void BlocksRenderer::face(const vec3& coord,
|
||||
vertex(coord + ( X + Y + Z) * s, region.u2, region.v2, tint);
|
||||
vertex(coord + (-X + Y + Z) * s, region.u1, region.v2, tint);
|
||||
}
|
||||
index(0, 1, 2, 0, 2, 3);
|
||||
index(0, 1, 2, 0, 2, 3);
|
||||
}
|
||||
|
||||
void BlocksRenderer::tetragonicFace(const vec3& coord, const vec3& p1,
|
||||
|
||||
@ -51,6 +51,7 @@ std::shared_ptr<Inventory> Inventories::clone(int64_t id) {
|
||||
auto origptr = reinterpret_cast<const Inventory*>(original.get());
|
||||
auto clone = std::make_shared<Inventory>(*origptr);
|
||||
clone->setId(level.getWorld()->getNextInventoryId());
|
||||
store(clone);
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,10 @@
|
||||
Inventory::Inventory(int64_t id, size_t size) : id(id), slots(size) {
|
||||
}
|
||||
|
||||
Inventory::Inventory(const Inventory& orig) {
|
||||
this->slots = orig.slots;
|
||||
}
|
||||
|
||||
ItemStack& Inventory::getSlot(size_t index) {
|
||||
return slots.at(index);
|
||||
}
|
||||
|
||||
@ -19,6 +19,8 @@ class Inventory : public Serializable {
|
||||
public:
|
||||
Inventory(int64_t id, size_t size);
|
||||
|
||||
Inventory(const Inventory& orig);
|
||||
|
||||
ItemStack& getSlot(size_t index);
|
||||
size_t findEmptySlot(size_t begin=0, size_t end=-1) const;
|
||||
size_t findSlotByItem(itemid_t id, size_t begin=0, size_t end=-1);
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "lua_util.h"
|
||||
#include "api_lua.h"
|
||||
#include "libgui.h"
|
||||
#include "libplayer.h"
|
||||
#include "libinventory.h"
|
||||
#include "../../../util/stringutil.h"
|
||||
|
||||
@ -33,7 +34,7 @@ lua::LuaState::LuaState() {
|
||||
setglobal(envName(0));
|
||||
}
|
||||
|
||||
const std::string lua::LuaState::envName(int env) const {
|
||||
const std::string lua::LuaState::envName(int env) {
|
||||
return "_ENV"+util::mangleid(env);
|
||||
}
|
||||
|
||||
@ -172,6 +173,11 @@ int lua::LuaState::pushnumber(luanumber x) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lua::LuaState::pushboolean(bool x) {
|
||||
lua_pushboolean(L, x);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lua::LuaState::pushivec3(luaint x, luaint y, luaint z) {
|
||||
lua::pushivec3(L, x, y, z);
|
||||
return 3;
|
||||
@ -233,6 +239,10 @@ lua::luanumber lua::LuaState::tonumber(int idx) {
|
||||
return lua_tonumber(L, idx);
|
||||
}
|
||||
|
||||
const char* lua::LuaState::tostring(int idx) {
|
||||
return lua_tostring(L, idx);
|
||||
}
|
||||
|
||||
void lua::LuaState::openlib(const std::string& name, const luaL_Reg* libfuncs, int nup) {
|
||||
lua_newtable(L);
|
||||
luaL_setfuncs(L, libfuncs, nup);
|
||||
|
||||
@ -25,12 +25,13 @@ namespace lua {
|
||||
LuaState();
|
||||
~LuaState();
|
||||
|
||||
const std::string envName(int env) const;
|
||||
static const std::string envName(int env);
|
||||
void loadbuffer(int env, const std::string& src, const std::string& file);
|
||||
int gettop() const;
|
||||
int pushivec3(luaint x, luaint y, luaint z);
|
||||
int pushinteger(luaint x);
|
||||
int pushnumber(luanumber x);
|
||||
int pushboolean(bool x);
|
||||
int pushstring(const std::string& str);
|
||||
int pushenv(int env);
|
||||
int pushvalue(int idx);
|
||||
@ -42,6 +43,7 @@ namespace lua {
|
||||
bool toboolean(int idx);
|
||||
luaint tointeger(int idx);
|
||||
luanumber tonumber(int idx);
|
||||
const char* tostring(int idx);
|
||||
int call(int argc);
|
||||
int callNoThrow(int argc);
|
||||
int execute(int env, const std::string& src, const std::string& file="<string>");
|
||||
|
||||
@ -142,61 +142,6 @@ int l_world_get_seed(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* == player library ==*/
|
||||
int l_player_get_pos(lua_State* L) {
|
||||
int playerid = lua_tointeger(L, 1);
|
||||
if (playerid != 1)
|
||||
return 0;
|
||||
glm::vec3 pos = scripting::level->player->hitbox->position;
|
||||
lua_pushnumber(L, pos.x);
|
||||
lua_pushnumber(L, pos.y);
|
||||
lua_pushnumber(L, pos.z);
|
||||
return 3;
|
||||
}
|
||||
|
||||
int l_player_get_rot(lua_State* L) {
|
||||
int playerid = lua_tointeger(L, 1);
|
||||
if (playerid != 1)
|
||||
return 0;
|
||||
glm::vec2 rot = scripting::level->player->cam;
|
||||
lua_pushnumber(L, rot.x);
|
||||
lua_pushnumber(L, rot.y);
|
||||
return 2;
|
||||
}
|
||||
|
||||
int l_player_set_rot(lua_State* L) {
|
||||
int playerid = lua_tointeger(L, 1);
|
||||
if (playerid != 1)
|
||||
return 0;
|
||||
lua::luanumber x = lua_tonumber(L, 2);
|
||||
lua::luanumber y = lua_tonumber(L, 3);
|
||||
glm::vec2& cam = scripting::level->player->cam;
|
||||
cam.x = x;
|
||||
cam.y = y;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int l_player_set_pos(lua_State* L) {
|
||||
int playerid = lua_tointeger(L, 1);
|
||||
if (playerid != 1)
|
||||
return 0;
|
||||
lua::luanumber x = lua_tonumber(L, 2);
|
||||
lua::luanumber y = lua_tonumber(L, 3);
|
||||
lua::luanumber z = lua_tonumber(L, 4);
|
||||
scripting::level->player->hitbox->position = glm::vec3(x, y, z);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int l_player_get_inv(lua_State* L) {
|
||||
int playerid = lua_tointeger(L, 1);
|
||||
if (playerid != 1)
|
||||
return 0;
|
||||
auto player = scripting::level->player;
|
||||
lua_pushinteger(L, player->getInventory()->getId());
|
||||
lua_pushinteger(L, player->getChosenSlot());
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* == item library == */
|
||||
int l_item_name(lua_State* L) {
|
||||
auto indices = scripting::content->getIndices();
|
||||
|
||||
@ -58,22 +58,6 @@ static const luaL_Reg worldlib [] = {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
/* == player library ==*/
|
||||
extern int l_player_get_pos(lua_State* L);
|
||||
extern int l_player_get_rot(lua_State* L);
|
||||
extern int l_player_set_rot(lua_State* L);
|
||||
extern int l_player_set_pos(lua_State* L);
|
||||
extern int l_player_get_inv(lua_State* L);
|
||||
|
||||
static const luaL_Reg playerlib [] = {
|
||||
{"get_pos", lua_wrap_errors<l_player_get_pos>},
|
||||
{"set_pos", lua_wrap_errors<l_player_set_pos>},
|
||||
{"get_rot", lua_wrap_errors<l_player_get_rot>},
|
||||
{"set_rot", lua_wrap_errors<l_player_set_rot>},
|
||||
{"get_inventory", lua_wrap_errors<l_player_get_inv>},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
/* == item library == */
|
||||
extern int l_item_name(lua_State* L);
|
||||
extern int l_item_index(lua_State* L);
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <iostream>
|
||||
#include "../scripting.h"
|
||||
#include "lua_util.h"
|
||||
#include "LuaState.h"
|
||||
|
||||
#include "../../../engine.h"
|
||||
#include "../../../assets/Assets.h"
|
||||
@ -23,12 +24,61 @@ static gui::UINode* getDocumentNode(lua_State* L, const std::string& name, const
|
||||
return node.get();
|
||||
}
|
||||
|
||||
static bool getattr(lua_State* L, gui::TrackBar* bar, const std::string& attr) {
|
||||
if (bar == nullptr)
|
||||
return false;
|
||||
if (attr == "value") {
|
||||
lua_pushnumber(L, bar->getValue()); return true;
|
||||
} else if (attr == "min") {
|
||||
lua_pushnumber(L, bar->getMin()); return true;
|
||||
} else if (attr == "max") {
|
||||
lua_pushnumber(L, bar->getMax());
|
||||
return true;
|
||||
} else if (attr == "step") {
|
||||
lua_pushnumber(L, bar->getStep());
|
||||
return true;
|
||||
} else if (attr == "trackWidth") {
|
||||
lua_pushnumber(L, bar->getTrackWidth());
|
||||
return true;
|
||||
} else if (attr == "trackColor") {
|
||||
return lua::pushcolor_arr(L, bar->getTrackColor());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool setattr(lua_State* L, gui::TrackBar* bar, const std::string& attr) {
|
||||
if (bar == nullptr)
|
||||
return false;
|
||||
if (attr == "value") {
|
||||
bar->setValue(lua_tonumber(L, 4));
|
||||
return true;
|
||||
} else if (attr == "min") {
|
||||
bar->setMin(lua_tonumber(L, 4));
|
||||
return true;
|
||||
} else if (attr == "max") {
|
||||
bar->setMax(lua_tonumber(L, 4));
|
||||
return true;
|
||||
} else if (attr == "step") {
|
||||
bar->setStep(lua_tonumber(L, 4));
|
||||
return true;
|
||||
} else if (attr == "trackWidth") {
|
||||
bar->setTrackWidth(lua_tonumber(L, 4));
|
||||
return true;
|
||||
} else if (attr == "trackColor") {
|
||||
bar->setTrackColor(lua::tocolor(L, 4));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool getattr(lua_State* L, gui::Button* button, const std::string& attr) {
|
||||
if (button == nullptr)
|
||||
return false;
|
||||
if (attr == "text") {
|
||||
lua_pushstring(L, util::wstr2str_utf8(button->getText()).c_str());
|
||||
return true;
|
||||
} else if (attr == "pressedColor") {
|
||||
return lua::pushcolor_arr(L, button->getPressedColor());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -43,12 +93,34 @@ static bool getattr(lua_State* L, gui::Label* label, const std::string& attr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool getattr(lua_State* L, gui::FullCheckBox* box, const std::string& attr) {
|
||||
if (box == nullptr)
|
||||
return false;
|
||||
if (attr == "checked") {
|
||||
lua_pushboolean(L, box->isChecked());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool setattr(lua_State* L, gui::Button* button, const std::string& attr) {
|
||||
if (button == nullptr)
|
||||
return false;
|
||||
if (attr == "text") {
|
||||
button->setText(util::str2wstr_utf8(lua_tostring(L, 4)));
|
||||
return true;
|
||||
} else if (attr == "pressedColor") {
|
||||
button->setPressedColor(lua::tocolor(L, 4));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool setattr(lua_State* L, gui::FullCheckBox* box, const std::string& attr) {
|
||||
if (box == nullptr)
|
||||
return false;
|
||||
if (attr == "checked") {
|
||||
box->setChecked(lua_toboolean(L, 4));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -75,12 +147,24 @@ int l_gui_getattr(lua_State* L) {
|
||||
return lua::pushvec2_arr(L, node->getCoord());
|
||||
} else if (attr == "size") {
|
||||
return lua::pushvec2_arr(L, node->getSize());
|
||||
} else if (attr == "hoverColor") {
|
||||
return lua::pushcolor_arr(L, node->getHoverColor());
|
||||
} else if (attr == "interactive") {
|
||||
lua_pushboolean(L, node->isInteractive());
|
||||
return 1;
|
||||
} else if (attr == "visible") {
|
||||
lua_pushboolean(L, node->isVisible());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (getattr(L, dynamic_cast<gui::Button*>(node), attr))
|
||||
return 1;
|
||||
if (getattr(L, dynamic_cast<gui::Label*>(node), attr))
|
||||
return 1;
|
||||
if (getattr(L, dynamic_cast<gui::TrackBar*>(node), attr))
|
||||
return 1;
|
||||
if (getattr(L, dynamic_cast<gui::FullCheckBox*>(node), attr))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -97,14 +181,36 @@ int l_gui_setattr(lua_State* L) {
|
||||
|
||||
auto node = getDocumentNode(L, docname, element);
|
||||
if (attr == "pos") {
|
||||
node->setCoord(lua::tovec2(L, 1));
|
||||
node->setCoord(lua::tovec2(L, 4));
|
||||
} else if (attr == "size") {
|
||||
node->setSize(lua::tovec2(L, 1));
|
||||
node->setSize(lua::tovec2(L, 4));
|
||||
} else if (attr == "color") {
|
||||
node->setColor(lua::tocolor(L, 4));
|
||||
} else if (attr == "hoverColor") {
|
||||
node->setHoverColor(lua::tocolor(L, 4));
|
||||
} else if (attr == "interactive") {
|
||||
node->setInteractive(lua_toboolean(L, 4));
|
||||
} else if (attr == "visible") {
|
||||
node->setVisible(lua_toboolean(L, 4));
|
||||
} else {
|
||||
if (setattr(L, dynamic_cast<gui::Button*>(node), attr))
|
||||
return 0;
|
||||
if (setattr(L, dynamic_cast<gui::Label*>(node), attr))
|
||||
return 0;
|
||||
if (setattr(L, dynamic_cast<gui::TrackBar*>(node), attr))
|
||||
return 0;
|
||||
if (setattr(L, dynamic_cast<gui::FullCheckBox*>(node), attr))
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int l_gui_get_env(lua_State* L) {
|
||||
auto name = lua_tostring(L, 1);
|
||||
auto doc = scripting::engine->getAssets()->getLayout(name);
|
||||
if (doc == nullptr) {
|
||||
luaL_error(L, "document '%s' not found", name);
|
||||
}
|
||||
lua_getglobal(L, lua::LuaState::envName(doc->getEnvironment()).c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1,16 +1,18 @@
|
||||
#ifndef LOGIC_SCRIPTING_API_LIBGUI_H_
|
||||
#define LOGIC_SCRIPTING_API_LIBGUI_H_
|
||||
|
||||
#include <lua.hpp>
|
||||
#include "lua_commons.h"
|
||||
|
||||
extern int l_gui_getviewport(lua_State* L);
|
||||
extern int l_gui_getattr(lua_State* L);
|
||||
extern int l_gui_setattr(lua_State* L);
|
||||
extern int l_gui_get_env(lua_State* L);
|
||||
|
||||
static const luaL_Reg guilib [] = {
|
||||
{"get_viewport", l_gui_getviewport},
|
||||
{"getattr", l_gui_getattr},
|
||||
{"setattr", l_gui_setattr},
|
||||
{"get_viewport", lua_wrap_errors<l_gui_getviewport>},
|
||||
{"getattr", lua_wrap_errors<l_gui_getattr>},
|
||||
{"setattr", lua_wrap_errors<l_gui_setattr>},
|
||||
{"get_env", lua_wrap_errors<l_gui_get_env>},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
@ -53,13 +53,6 @@ int l_hud_open_block(lua_State* L) {
|
||||
}
|
||||
|
||||
auto id = scripting::blocks->createBlockInventory(x, y, z);
|
||||
if (id == 0) {
|
||||
luaL_error(L,
|
||||
"block '%s' at %d %d %d has no inventory",
|
||||
def->name.c_str(),
|
||||
x, y, z
|
||||
);
|
||||
}
|
||||
|
||||
scripting::hud->openInventory(
|
||||
glm::ivec3(x, y, z), layout, scripting::level->inventories->get(id)
|
||||
|
||||
64
src/logic/scripting/lua/libplayer.cpp
Normal file
64
src/logic/scripting/lua/libplayer.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
#include "libplayer.h"
|
||||
#include "../scripting.h"
|
||||
#include "../../../world/Level.h"
|
||||
#include "../../../objects/Player.h"
|
||||
#include "../../../physics/Hitbox.h"
|
||||
#include "../../../window/Camera.h"
|
||||
#include "../../../items/Inventory.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
/* == player library ==*/
|
||||
int l_player_get_pos(lua_State* L) {
|
||||
int playerid = lua_tointeger(L, 1);
|
||||
if (playerid != 1)
|
||||
return 0;
|
||||
glm::vec3 pos = scripting::level->player->hitbox->position;
|
||||
lua_pushnumber(L, pos.x);
|
||||
lua_pushnumber(L, pos.y);
|
||||
lua_pushnumber(L, pos.z);
|
||||
return 3;
|
||||
}
|
||||
|
||||
int l_player_get_rot(lua_State* L) {
|
||||
int playerid = lua_tointeger(L, 1);
|
||||
if (playerid != 1)
|
||||
return 0;
|
||||
glm::vec2 rot = scripting::level->player->cam;
|
||||
lua_pushnumber(L, rot.x);
|
||||
lua_pushnumber(L, rot.y);
|
||||
return 2;
|
||||
}
|
||||
|
||||
int l_player_set_rot(lua_State* L) {
|
||||
int playerid = lua_tointeger(L, 1);
|
||||
if (playerid != 1)
|
||||
return 0;
|
||||
lua::luanumber x = lua_tonumber(L, 2);
|
||||
lua::luanumber y = lua_tonumber(L, 3);
|
||||
glm::vec2& cam = scripting::level->player->cam;
|
||||
cam.x = x;
|
||||
cam.y = y;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int l_player_set_pos(lua_State* L) {
|
||||
int playerid = lua_tointeger(L, 1);
|
||||
if (playerid != 1)
|
||||
return 0;
|
||||
lua::luanumber x = lua_tonumber(L, 2);
|
||||
lua::luanumber y = lua_tonumber(L, 3);
|
||||
lua::luanumber z = lua_tonumber(L, 4);
|
||||
scripting::level->player->hitbox->position = glm::vec3(x, y, z);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int l_player_get_inv(lua_State* L) {
|
||||
int playerid = lua_tointeger(L, 1);
|
||||
if (playerid != 1)
|
||||
return 0;
|
||||
auto player = scripting::level->player;
|
||||
lua_pushinteger(L, player->getInventory()->getId());
|
||||
lua_pushinteger(L, player->getChosenSlot());
|
||||
return 2;
|
||||
}
|
||||
22
src/logic/scripting/lua/libplayer.h
Normal file
22
src/logic/scripting/lua/libplayer.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef LOGIC_SCRIPTING_LUA_LIBPLAYER_H_
|
||||
#define LOGIC_SCRIPTING_LUA_LIBPLAYER_H_
|
||||
|
||||
#include "lua_commons.h"
|
||||
|
||||
/* == player library ==*/
|
||||
extern int l_player_get_pos(lua_State* L);
|
||||
extern int l_player_get_rot(lua_State* L);
|
||||
extern int l_player_set_rot(lua_State* L);
|
||||
extern int l_player_set_pos(lua_State* L);
|
||||
extern int l_player_get_inv(lua_State* L);
|
||||
|
||||
static const luaL_Reg playerlib [] = {
|
||||
{"get_pos", lua_wrap_errors<l_player_get_pos>},
|
||||
{"set_pos", lua_wrap_errors<l_player_set_pos>},
|
||||
{"get_rot", lua_wrap_errors<l_player_get_rot>},
|
||||
{"set_rot", lua_wrap_errors<l_player_set_rot>},
|
||||
{"get_inventory", lua_wrap_errors<l_player_get_inv>},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
#endif // LOGIC_SCRIPTING_LUA_LIBPLAYER_H_
|
||||
@ -25,4 +25,4 @@ template <lua_CFunction func> int lua_wrap_errors(lua_State *L) {
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // LOGIC_SCRIPTING_LUA_H_
|
||||
#endif // LOGIC_SCRIPTING_LUA_H_
|
||||
|
||||
@ -87,12 +87,31 @@ namespace lua {
|
||||
}
|
||||
|
||||
inline glm::vec2 tovec2(lua_State* L, int idx) {
|
||||
lua_rawgeti(L, idx, 1);
|
||||
lua_pushvalue(L, idx);
|
||||
lua_rawgeti(L, -1, 1);
|
||||
lua::luanumber x = lua_tonumber(L, -1); lua_pop(L, -1);
|
||||
lua_rawgeti(L, idx, 1);
|
||||
lua_rawgeti(L, -2, 2);
|
||||
lua::luanumber y = lua_tonumber(L, -1); lua_pop(L, -1);
|
||||
lua_pop(L, -1);
|
||||
return glm::vec2(x, y);
|
||||
}
|
||||
|
||||
inline glm::vec4 tocolor(lua_State* L, int idx) {
|
||||
lua_pushvalue(L, idx);
|
||||
if (!lua_istable(L, -1)) {
|
||||
luaL_error(L, "RGBA array required");
|
||||
}
|
||||
lua_rawgeti(L, -1, 1);
|
||||
lua::luanumber r = lua_tonumber(L, -1); lua_pop(L, -1);
|
||||
lua_rawgeti(L, -2, 2);
|
||||
lua::luanumber g = lua_tonumber(L, -1); lua_pop(L, -1);
|
||||
lua_rawgeti(L, -3, 3);
|
||||
lua::luanumber b = lua_tonumber(L, -1); lua_pop(L, -1);
|
||||
lua_rawgeti(L, -4, 4);
|
||||
lua::luanumber a = lua_tonumber(L, -1); lua_pop(L, -1);
|
||||
lua_pop(L, -1);
|
||||
return glm::vec4(r/255, g/255, b/255, a/255);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // LOGIC_SCRIPTING_LUA_UTIL_H_
|
||||
|
||||
@ -124,6 +124,9 @@ void scripting::on_world_quit() {
|
||||
state->callNoThrow(0);
|
||||
}
|
||||
}
|
||||
if (state->getglobal("__scripts_cleanup")) {
|
||||
state->callNoThrow(0);
|
||||
}
|
||||
scripting::level = nullptr;
|
||||
scripting::content = nullptr;
|
||||
scripting::indices = nullptr;
|
||||
|
||||
@ -17,7 +17,11 @@ runnable scripting::create_runnable(
|
||||
const std::string& file
|
||||
) {
|
||||
return [=](){
|
||||
state->execute(env, src, file);
|
||||
try {
|
||||
state->execute(env, src, file);
|
||||
} catch (const lua::luaerror& err) {
|
||||
std::cerr << err.what() << std::endl;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -47,6 +51,49 @@ wstringconsumer scripting::create_wstring_consumer(
|
||||
};
|
||||
}
|
||||
|
||||
wstringsupplier scripting::create_wstring_supplier(
|
||||
int env,
|
||||
const std::string& src,
|
||||
const std::string& file
|
||||
) {
|
||||
return [=](){
|
||||
if (processCallback(env, src, file)) {
|
||||
state->callNoThrow(0);
|
||||
auto str = state->tostring(-1); state->pop();
|
||||
return util::str2wstr_utf8(str);
|
||||
}
|
||||
return std::wstring(L"");
|
||||
};
|
||||
}
|
||||
|
||||
boolconsumer scripting::create_bool_consumer(
|
||||
int env,
|
||||
const std::string& src,
|
||||
const std::string& file
|
||||
) {
|
||||
return [=](bool x){
|
||||
if (processCallback(env, src, file)) {
|
||||
state->pushboolean(x);
|
||||
state->callNoThrow(1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
boolsupplier scripting::create_bool_supplier(
|
||||
int env,
|
||||
const std::string& src,
|
||||
const std::string& file
|
||||
) {
|
||||
return [=](){
|
||||
if (processCallback(env, src, file)) {
|
||||
state->callNoThrow(0);
|
||||
bool x = state->toboolean(-1); state->pop();
|
||||
return x;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
doubleconsumer scripting::create_number_consumer(
|
||||
int env,
|
||||
const std::string& src,
|
||||
|
||||
@ -18,6 +18,24 @@ namespace scripting {
|
||||
const std::string& file="<string>"
|
||||
);
|
||||
|
||||
wstringsupplier create_wstring_supplier(
|
||||
int env,
|
||||
const std::string& src,
|
||||
const std::string& file="<string>"
|
||||
);
|
||||
|
||||
boolconsumer create_bool_consumer(
|
||||
int env,
|
||||
const std::string& src,
|
||||
const std::string& file="<string>"
|
||||
);
|
||||
|
||||
boolsupplier create_bool_supplier(
|
||||
int env,
|
||||
const std::string& src,
|
||||
const std::string& file="<string>"
|
||||
);
|
||||
|
||||
doubleconsumer create_number_consumer(
|
||||
int env,
|
||||
const std::string& src,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user