add 'on_breaking', 'on_block_breaking' events

This commit is contained in:
MihailRis 2024-12-21 14:09:17 +03:00
parent c3f22c6854
commit 4363883728
5 changed files with 60 additions and 82 deletions

View File

@ -96,11 +96,12 @@ struct ContentPackStats {
};
struct WorldFuncsSet {
bool onblockplaced : 1;
bool onblockreplaced : 1;
bool onblockbroken : 1;
bool onblockinteract : 1;
bool onplayertick : 1;
bool onblockplaced;
bool onblockreplaced;
bool onblockbreaking;
bool onblockbroken;
bool onblockinteract;
bool onplayertick;
};
class ContentPackRuntime {

View File

@ -544,6 +544,7 @@ void PlayerController::updateInteraction(float delta) {
}
auto& target = indices->blocks.require(vox->id);
if (lclick) {
scripting::on_block_breaking(&player, target, iend);
if (player.isInstantDestruction() && target.breakable) {
blocksController.breakBlock(
&player, target, iend.x, iend.y, iend.z

View File

@ -336,16 +336,24 @@ void scripting::random_update_block(const Block& block, const glm::ivec3& pos) {
});
}
void scripting::on_block_placed(
Player* player, const Block& block, const glm::ivec3& pos
/// TODO: replace template with index
template<bool WorldFuncsSet::*worldfunc>
static bool on_block_common(
const std::string& suffix,
bool blockfunc,
Player* player,
const Block& block,
const glm::ivec3& pos
) {
if (block.rt.funcsset.onplaced) {
std::string name = block.name + ".placed";
lua::emit_event(lua::get_main_state(), name, [pos, player](auto L) {
lua::pushivec_stack(L, pos);
lua::pushinteger(L, player ? player->getId() : -1);
return 4;
});
bool result = false;
if (blockfunc) {
std::string name = block.name + "." + suffix;
result =
lua::emit_event(lua::get_main_state(), name, [pos, player](auto L) {
lua::pushivec_stack(L, pos);
lua::pushinteger(L, player->getId());
return 4;
});
}
auto args = [&](lua::State* L) {
lua::pushinteger(L, block.rt.id);
@ -354,93 +362,53 @@ void scripting::on_block_placed(
return 5;
};
for (auto& [packid, pack] : content->getPacks()) {
if (pack->worldfuncsset.onblockplaced) {
if (pack->worldfuncsset.*worldfunc) {
lua::emit_event(
lua::get_main_state(), packid + ":.blockplaced", args
lua::get_main_state(), packid + ":.block" + suffix, args
);
}
}
return result;
}
void scripting::on_block_placed(
Player* player, const Block& block, const glm::ivec3& pos
) {
on_block_common<&WorldFuncsSet::onblockplaced>(
"placed", block.rt.funcsset.onplaced, player, block, pos
);
}
void scripting::on_block_replaced(
Player* player, const Block& block, const glm::ivec3& pos
) {
if (block.rt.funcsset.onreplaced) {
std::string name = block.name + ".replaced";
lua::emit_event(lua::get_main_state(), name, [pos, player](auto L) {
lua::pushivec_stack(L, pos);
lua::pushinteger(L, player ? player->getId() : -1);
return 4;
});
}
auto args = [&](lua::State* L) {
lua::pushinteger(L, block.rt.id);
lua::pushivec_stack(L, pos);
lua::pushinteger(L, player ? player->getId() : -1);
return 5;
};
for (auto& [packid, pack] : content->getPacks()) {
if (pack->worldfuncsset.onblockreplaced) {
lua::emit_event(
lua::get_main_state(), packid + ":.blockreplaced", args
);
}
}
on_block_common<&WorldFuncsSet::onblockreplaced>(
"replaced", block.rt.funcsset.onreplaced, player, block, pos
);
}
void scripting::on_block_breaking(
Player* player, const Block& block, const glm::ivec3& pos
) {
on_block_common<&WorldFuncsSet::onblockbreaking>(
"breaking", block.rt.funcsset.onbreaking, player, block, pos
);
}
void scripting::on_block_broken(
Player* player, const Block& block, const glm::ivec3& pos
) {
if (block.rt.funcsset.onbroken) {
std::string name = block.name + ".broken";
lua::emit_event(
lua::get_main_state(),
name,
[pos, player](auto L) {
lua::pushivec_stack(L, pos);
lua::pushinteger(L, player ? player->getId() : -1);
return 4;
}
);
}
auto args = [&](lua::State* L) {
lua::pushinteger(L, block.rt.id);
lua::pushivec_stack(L, pos);
lua::pushinteger(L, player ? player->getId() : -1);
return 5;
};
for (auto& [packid, pack] : content->getPacks()) {
if (pack->worldfuncsset.onblockbroken) {
lua::emit_event(
lua::get_main_state(), packid + ":.blockbroken", args
);
}
}
on_block_common<&WorldFuncsSet::onblockbroken>(
"broken", block.rt.funcsset.onbroken, player, block, pos
);
}
bool scripting::on_block_interact(
Player* player, const Block& block, const glm::ivec3& pos
) {
std::string name = block.name + ".interact";
auto result = lua::emit_event(lua::get_main_state(), name, [pos, player](auto L) {
lua::pushivec_stack(L, pos);
lua::pushinteger(L, player->getId());
return 4;
});
auto args = [&](lua::State* L) {
lua::pushinteger(L, block.rt.id);
lua::pushivec_stack(L, pos);
lua::pushinteger(L, player ? player->getId() : -1);
return 5;
};
for (auto& [packid, pack] : content->getPacks()) {
if (pack->worldfuncsset.onblockinteract) {
lua::emit_event(
lua::get_main_state(), packid + ":.blockinteract", args
);
}
}
return result;
return on_block_common<&WorldFuncsSet::onblockinteract>(
"interact", block.rt.funcsset.oninteract, player, block, pos
);
}
void scripting::on_player_tick(Player* player, int tps) {
@ -804,6 +772,8 @@ void scripting::load_content_script(
funcsset.update = register_event(env, "on_update", prefix + ".update");
funcsset.randupdate =
register_event(env, "on_random_update", prefix + ".randupdate");
funcsset.onbreaking =
register_event(env, "on_breaking", prefix + ".breaking");
funcsset.onbroken = register_event(env, "on_broken", prefix + ".broken");
funcsset.onplaced = register_event(env, "on_placed", prefix + ".placed");
funcsset.onreplaced =
@ -857,6 +827,8 @@ void scripting::load_world_script(
register_event(env, "on_world_quit", prefix + ":.worldquit");
funcsset.onblockplaced =
register_event(env, "on_block_placed", prefix + ":.blockplaced");
funcsset.onblockbreaking =
register_event(env, "on_block_breaking", prefix + ":.blockbreaking");
funcsset.onblockbroken =
register_event(env, "on_block_broken", prefix + ":.blockbroken");
funcsset.onblockreplaced =

View File

@ -77,6 +77,9 @@ namespace scripting {
void on_block_replaced(
Player* player, const Block& block, const glm::ivec3& pos
);
void on_block_breaking(
Player* player, const Block& block, const glm::ivec3& pos
);
void on_block_broken(
Player* player, const Block& block, const glm::ivec3& pos
);

View File

@ -38,6 +38,7 @@ struct BlockFuncsSet {
bool init : 1;
bool update : 1;
bool onplaced : 1;
bool onbreaking : 1;
bool onbroken : 1;
bool onreplaced : 1;
bool oninteract : 1;