rewriting on_inventory_interact

This commit is contained in:
Xertis 2026-03-16 00:53:57 +03:00
parent f2684edf1f
commit 8ae35c0a5e
6 changed files with 62 additions and 21 deletions

View file

@ -221,6 +221,18 @@ function on_hud_close(playerid: int)
Called on world close (before saving)
```lua
function on_inventory_interact(invid: int, slot: int, mode: int, action: int)
```
Triggered when a player interacts with inventory slots.
| ACTION / MODE | (0) PRIMARY | (1) SECONDARY |
| ------------- | -------------------------------------------------- | ------------------------------------------------------ |
| (0) PUT | Places all items; if occupied, swaps them. | Places a single item from the cursor into the slot. |
| (1) TAKE | Picks up all items from the slot. | Picks up half of the items from the slot (rounded up). |
| (2) SHARE | Triggers the share event for the inventory layout. | Undefined |
## *events* library
```lua

View file

@ -231,11 +231,15 @@ function on_hud_close(playerid: int)
Вызывается при выходе из мира, перед его сохранением.
```lua
function on_hud_inventory_interact"(invid: int, slot: int, action: int)
function on_inventory_interact(invid: int, slot: int, mode: int, action: int)
```
Вызывается при взаимодействии со слотом игрока.
**action** отвечает за тип взаимодействия (0 - левый клик, 1 - правый клик, 2 - левый клик + шифт)
Вызывается при взаимодействии со слотами игроком
| ACTION / MODE | (0) PRIMARY | (1) SECONDARY |
| --------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------- |
| `(0) PUT` | Кладёт все предметы в слот, если другой предмет в слоте - обмен | Кладёт в слот один предмет из слота курсора |
| `(1) TAKE` | Забирает все предметы из слота | Берёт половину предметов из слота (округление вверх) |
| `(2) SHARE` | Вызывает share ивент у макета инвентаря | Не определён |
## События ECS
События **ECS** описаны [тут](ecs.md#события-компонента)

View file

@ -350,57 +350,68 @@ bool SlotView::isHighlighted() const {
void SlotView::performLeftClick(ItemStack& stack, ItemStack& grabbed) {
const auto& input = gui.getInput();
const int action = 0;
const int mode = PRIMARY;
int action;
if (layout.taking && input.pressed(Keycode::LEFT_SHIFT)) {
action = SHARE;
if (layout.shareFunc) {
layout.shareFunc(layout.index, stack);
}
if (layout.updateFunc) {
layout.updateFunc(layout.index, stack);
}
scripting::on_inventory_interact(inventoryId, layout.index, action | 2);
scripting::on_inventory_interact(inventoryId, layout.index, mode, action);
return;
}
if (!layout.itemSource && stack.accepts(grabbed) && layout.placing) {
action = PUT;
stack.move(grabbed, *content->getIndices());
} else {
if (layout.itemSource) {
if (grabbed.isEmpty()) {
action = TAKE;
grabbed.set(stack);
} else {
action = PUT;
grabbed.clear();
}
} else if (grabbed.isEmpty()) {
if (layout.taking) {
action = TAKE;
std::swap(grabbed, stack);
}
} else if (layout.taking && layout.placing) {
action = PUT;
std::swap(grabbed, stack);
}
}
scripting::on_inventory_interact(inventoryId, layout.index, action);
scripting::on_inventory_interact(inventoryId, layout.index, mode, action);
}
void SlotView::performRightClick(ItemStack& stack, ItemStack& grabbed) {
const auto& input = gui.getInput();
const int action = 1;
const int mode = SECONDARY;
int action = PUT;
if (layout.rightClick) {
layout.rightClick(inventoryId, stack);
if (layout.updateFunc) {
layout.updateFunc(layout.index, stack);
}
scripting::on_inventory_interact(inventoryId, layout.index, action);
scripting::on_inventory_interact(inventoryId, layout.index, mode, PUT);
return;
}
if (layout.itemSource) {
scripting::on_inventory_interact(inventoryId, layout.index, action);
scripting::on_inventory_interact(inventoryId, layout.index, mode, TAKE);
return;
}
if (grabbed.isEmpty()) {
if (!stack.isEmpty() && layout.taking) {
action = TAKE;
grabbed.set(std::move(stack));
int halfremain = stack.getCount() / 2;
grabbed.setCount(stack.getCount() - halfremain);
@ -411,17 +422,19 @@ void SlotView::performRightClick(ItemStack& stack, ItemStack& grabbed) {
stack = ItemStack(0, 0);
}
}
scripting::on_inventory_interact(inventoryId, layout.index, action);
scripting::on_inventory_interact(inventoryId, layout.index, mode, action);
return;
}
auto& stackDef = content->getIndices()->items.require(stack.getItemId());
if (!layout.placing) {
scripting::on_inventory_interact(inventoryId, layout.index, action);
scripting::on_inventory_interact(inventoryId, layout.index, mode, PUT);
return;
}
auto& stackDef = content->getIndices()->items.require(stack.getItemId());
if (stack.isEmpty()) {
action = PUT;
itemcount_t count = grabbed.getCount();
stack.set(std::move(grabbed));
stack.setCount(1);
@ -430,13 +443,13 @@ void SlotView::performRightClick(ItemStack& stack, ItemStack& grabbed) {
} else {
grabbed = ItemStack(stack.getItemId(), count - 1);
}
} else if (stack.accepts(grabbed) &&
stack.getCount() < stackDef.stackSize) {
} else if (stack.accepts(grabbed) && stack.getCount() < stackDef.stackSize) {
action = PUT;
stack.setCount(stack.getCount() + 1);
grabbed.setCount(grabbed.getCount() - 1);
}
scripting::on_inventory_interact(inventoryId, layout.index, action);
scripting::on_inventory_interact(inventoryId, layout.index, mode, action);
}
void SlotView::clicked(Mousecode button) {

View file

@ -56,6 +56,17 @@ namespace gui {
ItemStack stack {};
std::wstring countStr;
} cache;
enum InteractionMode {
PRIMARY = 0,
SECONDARY = 1
};
enum InteractionAction {
PUT = 0,
TAKE = 1,
SHARE = 2,
};
const Content* content = nullptr;
SlotLayout layout;

View file

@ -108,7 +108,7 @@ namespace scripting {
void on_inventory_open(const Player* player, const Inventory& inventory);
void on_inventory_closed(const Player* player, const Inventory& inventory);
void on_inventory_interact(int invid, int slot, int action);
void on_inventory_interact(int invid, int slot, int mode, int action);
void on_player_tick(Player* player, int tps);

View file

@ -93,17 +93,18 @@ void scripting::on_frontend_close() {
scripting::post_processing = nullptr;
}
void scripting::on_inventory_interact(int invid, int slot, int action) {
void scripting::on_inventory_interact(int invid, int slot, int mode, int action) {
auto L = lua::get_main_state();
for (auto& pack : content_control->getAllContentPacks()) {
lua::emit_event(
L,
pack.id + ":.hudinventoryinteract",
pack.id + ":.inventoryinteract",
[&](lua::State* L) {
lua::pushinteger(L, invid);
lua::pushinteger(L, slot);
lua::pushinteger(L, mode);
lua::pushinteger(L, action);
return 3;
return 4;
}
);
}
@ -125,7 +126,7 @@ void scripting::load_hud_script(
register_event(env, "on_hud_open", packid + ":.hudopen");
register_event(env, "on_hud_render", packid + ":.hudrender");
register_event(env, "on_hud_close", packid + ":.hudclose");
register_event(env, "on_hud_inventory_interact", packid + ":.hudinventoryinteract");
register_event(env, "on_inventory_interact", packid + ":.inventoryinteract");
}
gui::PageLoaderFunc scripting::create_page_loader() {