add 'on_block_removed' event
This commit is contained in:
parent
b3e5f2a1c0
commit
f721731ecc
@ -1,8 +1,9 @@
|
|||||||
local updating_blocks = {}
|
local updating_blocks = {}
|
||||||
local present_queues = {}
|
local present_queues = {}
|
||||||
local TYPE_REGISTER = 1
|
local REGISTER_BIT = 0x1
|
||||||
local TYPE_UPDATING = 2
|
local UPDATING_BIT = 0x2
|
||||||
local TYPE_PRESENT = 4
|
local PRESENT_BIT = 0x4
|
||||||
|
local REMOVED_BIT = 0x8
|
||||||
|
|
||||||
block.__perform_ticks = function(delta)
|
block.__perform_ticks = function(delta)
|
||||||
for id, entry in pairs(updating_blocks) do
|
for id, entry in pairs(updating_blocks) do
|
||||||
@ -25,7 +26,7 @@ block.__perform_ticks = function(delta)
|
|||||||
end
|
end
|
||||||
for id, queue in pairs(present_queues) do
|
for id, queue in pairs(present_queues) do
|
||||||
queue.timer = queue.timer + delta
|
queue.timer = queue.timer + delta
|
||||||
local steps = math.floor(queue.timer / queue.delta * #queue / 4)
|
local steps = math.floor(queue.timer / queue.delta * #queue / 3)
|
||||||
if steps == 0 then
|
if steps == 0 then
|
||||||
goto continue
|
goto continue
|
||||||
end
|
end
|
||||||
@ -33,16 +34,15 @@ block.__perform_ticks = function(delta)
|
|||||||
local event = queue.event
|
local event = queue.event
|
||||||
local update_list = updating_blocks[id]
|
local update_list = updating_blocks[id]
|
||||||
for i=1, steps do
|
for i=1, steps do
|
||||||
local index = #queue - 3
|
local index = #queue - 2
|
||||||
if index <= 0 then
|
if index <= 0 then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
local is_register = queue[index]
|
local x = queue[index]
|
||||||
local x = queue[index + 1]
|
local y = queue[index + 1]
|
||||||
local y = queue[index + 2]
|
local z = queue[index + 2]
|
||||||
local z = queue[index + 3]
|
|
||||||
|
|
||||||
for j=1,4 do
|
for j=1,3 do
|
||||||
table.remove(queue, index)
|
table.remove(queue, index)
|
||||||
end
|
end
|
||||||
events.emit(event, x, y, z)
|
events.emit(event, x, y, z)
|
||||||
@ -65,6 +65,10 @@ block.__process_register_events = function()
|
|||||||
if not register_events then
|
if not register_events then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local emit_event = events.emit
|
||||||
|
local removed_events = {}
|
||||||
|
|
||||||
for i=1, #register_events, 4 do
|
for i=1, #register_events, 4 do
|
||||||
local header = register_events[i]
|
local header = register_events[i]
|
||||||
local event_bits = bit.band(header, 0xFFFF)
|
local event_bits = bit.band(header, 0xFFFF)
|
||||||
@ -73,11 +77,21 @@ block.__process_register_events = function()
|
|||||||
local y = register_events[i + 2]
|
local y = register_events[i + 2]
|
||||||
local z = register_events[i + 3]
|
local z = register_events[i + 3]
|
||||||
|
|
||||||
local is_register = bit.band(event_bits, TYPE_REGISTER) ~= 0
|
local is_register = bit.band(event_bits, REGISTER_BIT) ~= 0
|
||||||
local is_updating = bit.band(event_bits, TYPE_UPDATING) ~= 0
|
local is_updating = bit.band(event_bits, UPDATING_BIT) ~= 0
|
||||||
local is_present = bit.band(event_bits, TYPE_PRESENT) ~= 0
|
local is_present = bit.band(event_bits, PRESENT_BIT) ~= 0
|
||||||
|
local is_removed = bit.band(event_bits, REMOVED_BIT) ~= 0
|
||||||
local list = updating_blocks[id]
|
local list = updating_blocks[id]
|
||||||
|
|
||||||
|
if not is_register and is_removed then
|
||||||
|
local rm_event = removed_events[id]
|
||||||
|
if not rm_event then
|
||||||
|
rm_event = block.name(id) .. ".blockremoved"
|
||||||
|
removed_events[id] = rm_event
|
||||||
|
end
|
||||||
|
emit_event(rm_event, x, y, z)
|
||||||
|
end
|
||||||
|
|
||||||
if not list and is_register and is_updating then
|
if not list and is_register and is_updating then
|
||||||
list = {}
|
list = {}
|
||||||
list.event = block.name(id) .. ".blocktick"
|
list.event = block.name(id) .. ".blocktick"
|
||||||
@ -100,7 +114,6 @@ block.__process_register_events = function()
|
|||||||
present_queue.updating = is_updating
|
present_queue.updating = is_updating
|
||||||
present_queues[id] = present_queue
|
present_queues[id] = present_queue
|
||||||
end
|
end
|
||||||
table.insert(present_queue, is_register)
|
|
||||||
table.insert(present_queue, x)
|
table.insert(present_queue, x)
|
||||||
table.insert(present_queue, y)
|
table.insert(present_queue, y)
|
||||||
table.insert(present_queue, z)
|
table.insert(present_queue, z)
|
||||||
|
|||||||
@ -357,6 +357,10 @@ function __vc_on_world_tick(tps)
|
|||||||
time.schedules.world:tick(1.0 / tps)
|
time.schedules.world:tick(1.0 / tps)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function __vc_process_before_quit()
|
||||||
|
block.__process_register_events()
|
||||||
|
end
|
||||||
|
|
||||||
function __vc_on_world_save()
|
function __vc_on_world_save()
|
||||||
local rule_values = {}
|
local rule_values = {}
|
||||||
for name, rule in pairs(rules.rules) do
|
for name, rule in pairs(rules.rules) do
|
||||||
|
|||||||
@ -109,6 +109,7 @@ LevelScreen::~LevelScreen() {
|
|||||||
scripting::on_frontend_close();
|
scripting::on_frontend_close();
|
||||||
// unblock all bindings
|
// unblock all bindings
|
||||||
input.getBindings().enableAll();
|
input.getBindings().enableAll();
|
||||||
|
playerController->getPlayer()->chunks->saveAndClear();
|
||||||
controller->onWorldQuit();
|
controller->onWorldQuit();
|
||||||
engine.getPaths().setCurrentWorldFolder("");
|
engine.getPaths().setCurrentWorldFolder("");
|
||||||
}
|
}
|
||||||
@ -278,5 +279,6 @@ void LevelScreen::onEngineShutdown() {
|
|||||||
if (hud->isInventoryOpen()) {
|
if (hud->isInventoryOpen()) {
|
||||||
hud->closeInventory();
|
hud->closeInventory();
|
||||||
}
|
}
|
||||||
|
controller->processBeforeQuit();
|
||||||
controller->saveWorld();
|
controller->saveWorld();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -366,7 +366,9 @@ void EngineController::reconfigPacks(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto world = controller->getLevel()->getWorld();
|
auto level = controller->getLevel();
|
||||||
|
auto world = level->getWorld();
|
||||||
|
controller->processBeforeQuit();
|
||||||
controller->saveWorld();
|
controller->saveWorld();
|
||||||
|
|
||||||
auto names = PacksManager::getNames(world->getPacks());
|
auto names = PacksManager::getNames(world->getPacks());
|
||||||
|
|||||||
@ -27,7 +27,8 @@ LevelController::LevelController(
|
|||||||
: settings(engine->getSettings()),
|
: settings(engine->getSettings()),
|
||||||
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),
|
||||||
|
localPlayer(clientPlayer) {
|
||||||
|
|
||||||
level->events->listen(LevelEventType::CHUNK_PRESENT, [](auto, Chunk* chunk) {
|
level->events->listen(LevelEventType::CHUNK_PRESENT, [](auto, Chunk* chunk) {
|
||||||
scripting::on_chunk_present(*chunk, chunk->flags.loaded);
|
scripting::on_chunk_present(*chunk, chunk->flags.loaded);
|
||||||
@ -121,6 +122,13 @@ void LevelController::update(float delta, bool pause) {
|
|||||||
level->entities->clean();
|
level->entities->clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LevelController::processBeforeQuit() {
|
||||||
|
if (localPlayer) {
|
||||||
|
localPlayer->chunks->saveAndClear();
|
||||||
|
}
|
||||||
|
scripting::process_before_quit();
|
||||||
|
}
|
||||||
|
|
||||||
void LevelController::saveWorld() {
|
void LevelController::saveWorld() {
|
||||||
auto world = level->getWorld();
|
auto world = level->getWorld();
|
||||||
if (world->isNameless()) {
|
if (world->isNameless()) {
|
||||||
|
|||||||
@ -20,6 +20,7 @@ class LevelController {
|
|||||||
std::unique_ptr<ChunksController> chunks;
|
std::unique_ptr<ChunksController> chunks;
|
||||||
|
|
||||||
util::Clock playerTickClock;
|
util::Clock playerTickClock;
|
||||||
|
Player* localPlayer;
|
||||||
public:
|
public:
|
||||||
LevelController(Engine* engine, std::unique_ptr<Level> level, Player* clientPlayer);
|
LevelController(Engine* engine, std::unique_ptr<Level> level, Player* clientPlayer);
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ public:
|
|||||||
/// @param pause is world and player simulation paused
|
/// @param pause is world and player simulation paused
|
||||||
void update(float delta, bool pause);
|
void update(float delta, bool pause);
|
||||||
|
|
||||||
|
void processBeforeQuit();
|
||||||
void saveWorld();
|
void saveWorld();
|
||||||
|
|
||||||
void onWorldQuit();
|
void onWorldQuit();
|
||||||
|
|||||||
@ -119,6 +119,7 @@ static int l_close_world(lua::State* L) {
|
|||||||
if (controller == nullptr) {
|
if (controller == nullptr) {
|
||||||
throw std::runtime_error("no world open");
|
throw std::runtime_error("no world open");
|
||||||
}
|
}
|
||||||
|
controller->processBeforeQuit();
|
||||||
bool save_world = lua::toboolean(L, 1);
|
bool save_world = lua::toboolean(L, 1);
|
||||||
if (save_world) {
|
if (save_world) {
|
||||||
controller->saveWorld();
|
controller->saveWorld();
|
||||||
|
|||||||
@ -341,6 +341,13 @@ void scripting::on_world_save() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scripting::process_before_quit() {
|
||||||
|
auto L = lua::get_main_state();
|
||||||
|
if (lua::getglobal(L, "__vc_process_before_quit")) {
|
||||||
|
lua::call_nothrow(L, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void scripting::on_world_quit() {
|
void scripting::on_world_quit() {
|
||||||
auto L = lua::get_main_state();
|
auto L = lua::get_main_state();
|
||||||
for (auto& pack : content_control->getAllContentPacks()) {
|
for (auto& pack : content_control->getAllContentPacks()) {
|
||||||
@ -677,6 +684,8 @@ void scripting::load_content_script(
|
|||||||
register_event(env, "on_blocks_tick", prefix + ".blockstick");
|
register_event(env, "on_blocks_tick", prefix + ".blockstick");
|
||||||
funcsset.onblockpresent =
|
funcsset.onblockpresent =
|
||||||
register_event(env, "on_block_present", prefix + ".blockpresent");
|
register_event(env, "on_block_present", prefix + ".blockpresent");
|
||||||
|
funcsset.onblockremoved =
|
||||||
|
register_event(env, "on_block_removed", prefix + ".blockremoved");
|
||||||
}
|
}
|
||||||
|
|
||||||
void scripting::load_content_script(
|
void scripting::load_content_script(
|
||||||
|
|||||||
@ -81,6 +81,7 @@ namespace scripting {
|
|||||||
void on_world_load(LevelController* controller);
|
void on_world_load(LevelController* controller);
|
||||||
void on_world_tick(int tps);
|
void on_world_tick(int tps);
|
||||||
void on_world_save();
|
void on_world_save();
|
||||||
|
void process_before_quit();
|
||||||
void on_world_quit();
|
void on_world_quit();
|
||||||
void cleanup(const std::vector<std::string>& nonReset);
|
void cleanup(const std::vector<std::string>& nonReset);
|
||||||
void on_blocks_tick(const Block& block, int tps);
|
void on_blocks_tick(const Block& block, int tps);
|
||||||
|
|||||||
@ -51,6 +51,7 @@ struct BlockFuncsSet {
|
|||||||
bool onblocktick : 1;
|
bool onblocktick : 1;
|
||||||
bool onblockstick : 1;
|
bool onblockstick : 1;
|
||||||
bool onblockpresent : 1;
|
bool onblockpresent : 1;
|
||||||
|
bool onblockremoved : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CoordSystem {
|
struct CoordSystem {
|
||||||
|
|||||||
@ -19,6 +19,7 @@ static uint8_t get_events_bits(const Block& def) {
|
|||||||
auto funcsset = def.rt.funcsset;
|
auto funcsset = def.rt.funcsset;
|
||||||
bits |= BlockRegisterEvent::UPDATING_BIT * funcsset.onblocktick;
|
bits |= BlockRegisterEvent::UPDATING_BIT * funcsset.onblocktick;
|
||||||
bits |= BlockRegisterEvent::PRESENT_EVENT_BIT * funcsset.onblockpresent;
|
bits |= BlockRegisterEvent::PRESENT_EVENT_BIT * funcsset.onblockpresent;
|
||||||
|
bits |= BlockRegisterEvent::REMOVED_EVENT_BIT * funcsset.onblockremoved;
|
||||||
return bits;
|
return bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,7 @@ struct BlockRegisterEvent {
|
|||||||
static inline constexpr uint8_t REGISTER_BIT = 0x1;
|
static inline constexpr uint8_t REGISTER_BIT = 0x1;
|
||||||
static inline constexpr uint8_t UPDATING_BIT = 0x2;
|
static inline constexpr uint8_t UPDATING_BIT = 0x2;
|
||||||
static inline constexpr uint8_t PRESENT_EVENT_BIT = 0x4;
|
static inline constexpr uint8_t PRESENT_EVENT_BIT = 0x4;
|
||||||
|
static inline constexpr uint8_t REMOVED_EVENT_BIT = 0x8;
|
||||||
uint8_t bits;
|
uint8_t bits;
|
||||||
blockid_t id;
|
blockid_t id;
|
||||||
glm::ivec3 coord;
|
glm::ivec3 coord;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user