commit
7615c85738
@ -126,6 +126,34 @@ function on_block_interact(blockid, x, y, z, playerid) -> bool
|
|||||||
|
|
||||||
Called on block RMB click interaction. Prevents block placing if **true** returned.
|
Called on block RMB click interaction. Prevents block placing if **true** returned.
|
||||||
|
|
||||||
|
### Chunk Events (world.lua)
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function on_chunk_present(x: int, z: int, loaded: bool)
|
||||||
|
```
|
||||||
|
|
||||||
|
Called after a chunk is generated/loaded. If a previously saved chunk is loaded, `loaded` will be true.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function on_chunk_remove(x: int, z: int)
|
||||||
|
```
|
||||||
|
|
||||||
|
Called when a chunk is unloaded from the world.
|
||||||
|
|
||||||
|
### Inventory Events (world.lua)
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function on_inventory_open(invid: int, playerid: int)
|
||||||
|
```
|
||||||
|
|
||||||
|
Called when the inventory is opened. If the inventory was not opened directly by the player, playerid will be -1.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function on_inventory_closed(invid: int, playerid: int)
|
||||||
|
```
|
||||||
|
|
||||||
|
Called when the inventory is closed.
|
||||||
|
|
||||||
## Layout events
|
## Layout events
|
||||||
|
|
||||||
Script *layouts/layout_name.xml.lua* events.
|
Script *layouts/layout_name.xml.lua* events.
|
||||||
|
|||||||
@ -126,6 +126,35 @@ function on_block_interact(blockid, x, y, z, playerid) -> bool
|
|||||||
|
|
||||||
Вызывается при нажатии на блок ПКМ. Предотвращает установку блоков, если возвращает `true`
|
Вызывается при нажатии на блок ПКМ. Предотвращает установку блоков, если возвращает `true`
|
||||||
|
|
||||||
|
### События чанков (world.lua)
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function on_chunk_present(x: int, z: int, loaded: bool)
|
||||||
|
```
|
||||||
|
|
||||||
|
Вызывается после генерации/загрузки чанка. В случае загрузки ранее сохраненного чанка `loaded` будет истинным.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function on_chunk_remove(x: int, z: int)
|
||||||
|
```
|
||||||
|
|
||||||
|
Вызывается при выгрузке чанка из мира.
|
||||||
|
|
||||||
|
### События инвентарей (world.lua)
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function on_inventory_open(invid: int, playerid: int)
|
||||||
|
```
|
||||||
|
|
||||||
|
Вызывается при открытии инвентаря. Если инвентарь был открыт не напрямую игроком, playerid будет равен -1.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function on_inventory_closed(invid: int, playerid: int)
|
||||||
|
```
|
||||||
|
|
||||||
|
Вызывается при закрытии инвентаря.
|
||||||
|
|
||||||
|
|
||||||
## События макета
|
## События макета
|
||||||
|
|
||||||
События прописываются в файле `layouts/имя_макета.xml.lua`.
|
События прописываются в файле `layouts/имя_макета.xml.lua`.
|
||||||
|
|||||||
@ -109,6 +109,10 @@ struct WorldFuncsSet {
|
|||||||
bool onblockbroken;
|
bool onblockbroken;
|
||||||
bool onblockinteract;
|
bool onblockinteract;
|
||||||
bool onplayertick;
|
bool onplayertick;
|
||||||
|
bool onchunkpresent;
|
||||||
|
bool onchunkremove;
|
||||||
|
bool oninventoryopen;
|
||||||
|
bool oninventoryclosed;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ContentPackRuntime {
|
class ContentPackRuntime {
|
||||||
|
|||||||
@ -413,6 +413,7 @@ std::shared_ptr<Inventory> Hud::openInventory(
|
|||||||
}
|
}
|
||||||
secondInvView->bind(inv, &content);
|
secondInvView->bind(inv, &content);
|
||||||
add(HudElement(hud_element_mode::inventory_bound, doc, secondUI, false));
|
add(HudElement(hud_element_mode::inventory_bound, doc, secondUI, false));
|
||||||
|
scripting::on_inventory_open(&player, *inv);
|
||||||
return inv;
|
return inv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,6 +448,8 @@ void Hud::openInventory(
|
|||||||
blockPos = block;
|
blockPos = block;
|
||||||
currentblockid = chunks.require(block.x, block.y, block.z).id;
|
currentblockid = chunks.require(block.x, block.y, block.z).id;
|
||||||
add(HudElement(hud_element_mode::inventory_bound, doc, blockUI, false));
|
add(HudElement(hud_element_mode::inventory_bound, doc, blockUI, false));
|
||||||
|
|
||||||
|
scripting::on_inventory_open(&player, *blockinv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hud::showExchangeSlot() {
|
void Hud::showExchangeSlot() {
|
||||||
@ -461,7 +464,6 @@ void Hud::showExchangeSlot() {
|
|||||||
exchangeSlot->setInteractive(false);
|
exchangeSlot->setInteractive(false);
|
||||||
exchangeSlot->setZIndex(1);
|
exchangeSlot->setZIndex(1);
|
||||||
gui.store(SlotView::EXCHANGE_SLOT_NAME, exchangeSlot);
|
gui.store(SlotView::EXCHANGE_SLOT_NAME, exchangeSlot);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hud::showOverlay(
|
void Hud::showOverlay(
|
||||||
@ -517,13 +519,18 @@ void Hud::dropExchangeSlot() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Hud::closeInventory() {
|
void Hud::closeInventory() {
|
||||||
|
if (blockUI) {
|
||||||
|
scripting::on_inventory_closed(&player, *blockUI->getInventory());
|
||||||
|
blockUI = nullptr;
|
||||||
|
}
|
||||||
|
if (secondInvView) {
|
||||||
|
scripting::on_inventory_closed(&player, *secondInvView->getInventory());
|
||||||
|
}
|
||||||
dropExchangeSlot();
|
dropExchangeSlot();
|
||||||
gui.remove(SlotView::EXCHANGE_SLOT_NAME);
|
gui.remove(SlotView::EXCHANGE_SLOT_NAME);
|
||||||
exchangeSlot = nullptr;
|
exchangeSlot = nullptr;
|
||||||
exchangeSlotInv = nullptr;
|
exchangeSlotInv = nullptr;
|
||||||
inventoryOpen = false;
|
inventoryOpen = false;
|
||||||
inventoryView = nullptr;
|
|
||||||
blockUI = nullptr;
|
|
||||||
secondUI = nullptr;
|
secondUI = nullptr;
|
||||||
|
|
||||||
for (auto& element : elements) {
|
for (auto& element : elements) {
|
||||||
|
|||||||
@ -89,7 +89,7 @@ WorldRenderer::WorldRenderer(
|
|||||||
) {
|
) {
|
||||||
auto& settings = engine.getSettings();
|
auto& settings = engine.getSettings();
|
||||||
level.events->listen(
|
level.events->listen(
|
||||||
EVT_CHUNK_HIDDEN,
|
LevelEventType::CHUNK_HIDDEN,
|
||||||
[this](LevelEventType, Chunk* chunk) { chunks->unload(chunk); }
|
[this](LevelEventType, Chunk* chunk) { chunks->unload(chunk); }
|
||||||
);
|
);
|
||||||
auto assets = engine.getAssets();
|
auto assets = engine.getAssets();
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
#include "scripting/scripting.hpp"
|
#include "scripting/scripting.hpp"
|
||||||
#include "lighting/Lighting.hpp"
|
#include "lighting/Lighting.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
|
#include "world/LevelEvents.hpp"
|
||||||
#include "world/Level.hpp"
|
#include "world/Level.hpp"
|
||||||
#include "world/World.hpp"
|
#include "world/World.hpp"
|
||||||
|
|
||||||
@ -26,6 +27,14 @@ LevelController::LevelController(
|
|||||||
level(std::move(levelPtr)),
|
level(std::move(levelPtr)),
|
||||||
chunks(std::make_unique<ChunksController>(*level)),
|
chunks(std::make_unique<ChunksController>(*level)),
|
||||||
playerTickClock(20, 3) {
|
playerTickClock(20, 3) {
|
||||||
|
|
||||||
|
level->events->listen(LevelEventType::CHUNK_PRESENT, [](auto, Chunk* chunk) {
|
||||||
|
scripting::on_chunk_present(*chunk, chunk->flags.loaded);
|
||||||
|
});
|
||||||
|
level->events->listen(LevelEventType::CHUNK_UNLOAD, [](auto, Chunk* chunk) {
|
||||||
|
scripting::on_chunk_remove(*chunk);
|
||||||
|
});
|
||||||
|
|
||||||
if (clientPlayer) {
|
if (clientPlayer) {
|
||||||
chunks->lighting = std::make_unique<Lighting>(
|
chunks->lighting = std::make_unique<Lighting>(
|
||||||
level->content, *clientPlayer->chunks
|
level->content, *clientPlayer->chunks
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
#include "util/stringutil.hpp"
|
#include "util/stringutil.hpp"
|
||||||
#include "util/timeutil.hpp"
|
#include "util/timeutil.hpp"
|
||||||
#include "voxels/Block.hpp"
|
#include "voxels/Block.hpp"
|
||||||
|
#include "voxels/Chunk.hpp"
|
||||||
#include "world/Level.hpp"
|
#include "world/Level.hpp"
|
||||||
#include "interfaces/Process.hpp"
|
#include "interfaces/Process.hpp"
|
||||||
|
|
||||||
@ -411,6 +412,65 @@ bool scripting::on_block_interact(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scripting::on_chunk_present(const Chunk& chunk, bool loaded) {
|
||||||
|
auto args = [&chunk, loaded](lua::State* L) {
|
||||||
|
lua::pushvec_stack<2>(L, {chunk.x, chunk.z});
|
||||||
|
lua::pushboolean(L, loaded);
|
||||||
|
return 3;
|
||||||
|
};
|
||||||
|
for (auto& [packid, pack] : content->getPacks()) {
|
||||||
|
if (pack->worldfuncsset.onchunkpresent) {
|
||||||
|
lua::emit_event(
|
||||||
|
lua::get_main_state(), packid + ":.chunkpresent", args
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void scripting::on_chunk_remove(const Chunk& chunk) {
|
||||||
|
auto args = [&chunk](lua::State* L) {
|
||||||
|
lua::pushvec_stack<2>(L, {chunk.x, chunk.z});
|
||||||
|
return 2;
|
||||||
|
};
|
||||||
|
for (auto& [packid, pack] : content->getPacks()) {
|
||||||
|
if (pack->worldfuncsset.onchunkremove) {
|
||||||
|
lua::emit_event(
|
||||||
|
lua::get_main_state(), packid + ":.chunkremove", args
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void scripting::on_inventory_open(const Player* player, const Inventory& inventory) {
|
||||||
|
auto args = [player, &inventory](lua::State* L) {
|
||||||
|
lua::pushinteger(L, inventory.getId());
|
||||||
|
lua::pushinteger(L, player ? player->getId() : -1);
|
||||||
|
return 2;
|
||||||
|
};
|
||||||
|
for (auto& [packid, pack] : content->getPacks()) {
|
||||||
|
if (pack->worldfuncsset.oninventoryopen) {
|
||||||
|
lua::emit_event(
|
||||||
|
lua::get_main_state(), packid + ":.inventoryopen", args
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void scripting::on_inventory_closed(const Player* player, const Inventory& inventory) {
|
||||||
|
auto args = [player, &inventory](lua::State* L) {
|
||||||
|
lua::pushinteger(L, inventory.getId());
|
||||||
|
lua::pushinteger(L, player ? player->getId() : -1);
|
||||||
|
return 2;
|
||||||
|
};
|
||||||
|
for (auto& [packid, pack] : content->getPacks()) {
|
||||||
|
if (pack->worldfuncsset.oninventoryclosed) {
|
||||||
|
lua::emit_event(
|
||||||
|
lua::get_main_state(), packid + ":.inventoryclosed", args
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void scripting::on_player_tick(Player* player, int tps) {
|
void scripting::on_player_tick(Player* player, int tps) {
|
||||||
auto args = [=](lua::State* L) {
|
auto args = [=](lua::State* L) {
|
||||||
lua::pushinteger(L, player ? player->getId() : -1);
|
lua::pushinteger(L, player ? player->getId() : -1);
|
||||||
@ -837,6 +897,14 @@ void scripting::load_world_script(
|
|||||||
register_event(env, "on_block_interact", prefix + ":.blockinteract");
|
register_event(env, "on_block_interact", prefix + ":.blockinteract");
|
||||||
funcsset.onplayertick =
|
funcsset.onplayertick =
|
||||||
register_event(env, "on_player_tick", prefix + ":.playertick");
|
register_event(env, "on_player_tick", prefix + ":.playertick");
|
||||||
|
funcsset.onchunkpresent =
|
||||||
|
register_event(env, "on_chunk_present", prefix + ":.chunkpresent");
|
||||||
|
funcsset.onchunkremove =
|
||||||
|
register_event(env, "on_chunk_remove", prefix + ":.chunkremove");
|
||||||
|
funcsset.oninventoryopen =
|
||||||
|
register_event(env, "on_inventory_open", prefix + ":.inventoryopen");
|
||||||
|
funcsset.oninventoryclosed =
|
||||||
|
register_event(env, "on_inventory_closed", prefix + ":.inventoryclosed");
|
||||||
}
|
}
|
||||||
|
|
||||||
void scripting::load_layout_script(
|
void scripting::load_layout_script(
|
||||||
|
|||||||
@ -17,6 +17,7 @@ struct ContentPack;
|
|||||||
class ContentIndices;
|
class ContentIndices;
|
||||||
class Level;
|
class Level;
|
||||||
class Block;
|
class Block;
|
||||||
|
class Chunk;
|
||||||
class Player;
|
class Player;
|
||||||
struct ItemDef;
|
struct ItemDef;
|
||||||
class Inventory;
|
class Inventory;
|
||||||
@ -84,6 +85,13 @@ namespace scripting {
|
|||||||
Player* player, const Block& block, const glm::ivec3& pos
|
Player* player, const Block& block, const glm::ivec3& pos
|
||||||
);
|
);
|
||||||
bool on_block_interact(Player* player, const Block& block, const glm::ivec3& pos);
|
bool on_block_interact(Player* player, const Block& block, const glm::ivec3& pos);
|
||||||
|
|
||||||
|
void on_chunk_present(const Chunk& chunk, bool loaded);
|
||||||
|
void on_chunk_remove(const Chunk& chunk);
|
||||||
|
|
||||||
|
void on_inventory_open(const Player* player, const Inventory& inventory);
|
||||||
|
void on_inventory_closed(const Player* player, const Inventory& inventory);
|
||||||
|
|
||||||
void on_player_tick(Player* player, int tps);
|
void on_player_tick(Player* player, int tps);
|
||||||
|
|
||||||
/// @brief Called on RMB click with the item selected
|
/// @brief Called on RMB click with the item selected
|
||||||
|
|||||||
@ -34,7 +34,7 @@ Chunks::Chunks(
|
|||||||
areaMap(w, d) {
|
areaMap(w, d) {
|
||||||
areaMap.setCenter(ox-w/2, oz-d/2);
|
areaMap.setCenter(ox-w/2, oz-d/2);
|
||||||
areaMap.setOutCallback([this](int, int, const auto& chunk) {
|
areaMap.setOutCallback([this](int, int, const auto& chunk) {
|
||||||
this->events->trigger(EVT_CHUNK_HIDDEN, chunk.get());
|
this->events->trigger(LevelEventType::CHUNK_HIDDEN, chunk.get());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,7 +323,7 @@ void Chunks::resize(uint32_t newW, uint32_t newD) {
|
|||||||
bool Chunks::putChunk(const std::shared_ptr<Chunk>& chunk) {
|
bool Chunks::putChunk(const std::shared_ptr<Chunk>& chunk) {
|
||||||
if (areaMap.set(chunk->x, chunk->z, chunk)) {
|
if (areaMap.set(chunk->x, chunk->z, chunk)) {
|
||||||
if (events) {
|
if (events) {
|
||||||
events->trigger(LevelEventType::EVT_CHUNK_SHOWN, chunk.get());
|
events->trigger(LevelEventType::CHUNK_SHOWN, chunk.get());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
#include "objects/Entities.hpp"
|
#include "objects/Entities.hpp"
|
||||||
#include "voxels/blocks_agent.hpp"
|
#include "voxels/blocks_agent.hpp"
|
||||||
#include "typedefs.hpp"
|
#include "typedefs.hpp"
|
||||||
|
#include "world/LevelEvents.hpp"
|
||||||
#include "world/Level.hpp"
|
#include "world/Level.hpp"
|
||||||
#include "world/World.hpp"
|
#include "world/World.hpp"
|
||||||
#include "Block.hpp"
|
#include "Block.hpp"
|
||||||
@ -125,6 +126,8 @@ std::shared_ptr<Chunk> GlobalChunks::create(int x, int z) {
|
|||||||
chunk->flags.loadedLights = true;
|
chunk->flags.loadedLights = true;
|
||||||
}
|
}
|
||||||
chunk->blocksMetadata = regions.getBlocksData(chunk->x, chunk->z);
|
chunk->blocksMetadata = regions.getBlocksData(chunk->x, chunk->z);
|
||||||
|
|
||||||
|
level.events->trigger(LevelEventType::CHUNK_PRESENT, chunk.get());
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -52,13 +52,14 @@ Level::Level(
|
|||||||
entities->setNextID(worldInfo.nextEntityId);
|
entities->setNextID(worldInfo.nextEntityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
events->listen(LevelEventType::EVT_CHUNK_SHOWN, [this](LevelEventType, Chunk* chunk) {
|
events->listen(LevelEventType::CHUNK_SHOWN, [this](LevelEventType, Chunk* chunk) {
|
||||||
chunks->incref(chunk);
|
chunks->incref(chunk);
|
||||||
});
|
});
|
||||||
events->listen(LevelEventType::EVT_CHUNK_HIDDEN, [this](LevelEventType, Chunk* chunk) {
|
events->listen(LevelEventType::CHUNK_HIDDEN, [this](LevelEventType, Chunk* chunk) {
|
||||||
chunks->decref(chunk);
|
chunks->decref(chunk);
|
||||||
});
|
});
|
||||||
chunks->setOnUnload([this](const Chunk& chunk) {
|
chunks->setOnUnload([this](Chunk& chunk) {
|
||||||
|
events->trigger(LevelEventType::CHUNK_UNLOAD, &chunk);
|
||||||
AABB aabb = chunk.getAABB();
|
AABB aabb = chunk.getAABB();
|
||||||
entities->despawn(entities->getAllInside(aabb));
|
entities->despawn(entities->getAllInside(aabb));
|
||||||
});
|
});
|
||||||
|
|||||||
@ -6,9 +6,11 @@
|
|||||||
|
|
||||||
class Chunk;
|
class Chunk;
|
||||||
|
|
||||||
enum LevelEventType {
|
enum class LevelEventType {
|
||||||
EVT_CHUNK_SHOWN,
|
CHUNK_SHOWN,
|
||||||
EVT_CHUNK_HIDDEN,
|
CHUNK_HIDDEN,
|
||||||
|
CHUNK_PRESENT,
|
||||||
|
CHUNK_UNLOAD,
|
||||||
};
|
};
|
||||||
|
|
||||||
using ChunkEventFunc = std::function<void(LevelEventType, Chunk*)>;
|
using ChunkEventFunc = std::function<void(LevelEventType, Chunk*)>;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user