Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Item/block groups #89

Merged
merged 5 commits into from
Mar 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/lua-api-block.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ Example:
draw_type = "solid" -- this is the default value
```

### `groups`

Groups of the block. They can be used in recipes, and can also filter Lua-defined inventory widgets.

See [Item#Attributes#groups](/lua-api-item#groups) for more details.

### `hardness`

Hardness of the block, affects mining speed.
Expand Down
9 changes: 9 additions & 0 deletions docs/lua-api-gui-inventory.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ gui:inventory {

## Attributes

### `filter`

Use a group as a filter for this inventory widget.

Example:
```
filter = "group:om_fuel"
```

### `inventory`

Details of the inventory to use.
Expand Down
25 changes: 13 additions & 12 deletions docs/lua-api-item.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,30 @@ mod:item {

## Attributes

### `burn_time`
### `groups`

Burn time of a fuel item.
Groups of the item. They can be used in recipes, and can also filter Lua-defined inventory widgets.

Each group must be set to `1` if present. Default value for each group is `0`, and it cannot exceeds `65535`.

Example:
```lua
burn_time = 200 -- example value for a coal item, default is 0
groups = {
om_fuel = 200 -- example burn time for a coal item
}
```

### `harvest_capability`
Engine groups always start with `om_` prefix. If you create your own groups, please prefix them with something to let people know that the group comes from your mod.

For a tool, set which blocks are easier to mine.
Available engine groups:

**Note:** This attribute would need more doc but it'll probably get removed soon.
- `om_fuel`: used in `default:furnace` and `MouseWidgetItem`, the value represents the burn time

### `is_fuel`
### `harvest_capability`

Defines if the item is valid furnace fuel or not.
For a tool, set which blocks are easier to mine.

Example:
```lua
is_fuel = false -- this is the default value
```
**Note:** This attribute would need more doc but it'll probably get removed soon.

### `id`

Expand Down
14 changes: 14 additions & 0 deletions docs/lua-api-mod.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Lua API: Mod API Overview

## Introduction

You can create a mod using this function:
```
LuaMod.new("mod_name")
```

Mod name should match this regex: `[a-zA-Z0-9_]+`

Everytime your define an `id` for a mod element, this name will be prepended to it.
For example, `myitem` will become `mymod:myitem`.

The name can't be `group` because this namespace is already used by the engine.

## Example

```lua
Expand Down
8 changes: 6 additions & 2 deletions docs/lua-api-recipe.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ result = {
Possible attributes:

- `id`: String ID of the item created.
- `amount`: Amount of items in the created stack
- `amount`: Amount of items in the created stack.

#### `pattern`

Expand All @@ -78,6 +78,8 @@ pattern = {

Mapping of the characters used in `pattern` to actual item string IDs.

**Note:** Keys can also be groups. See [Item#Attributes#groups](/lua-api-item#groups) for more details.

Example:
```lua
keys = {
Expand All @@ -103,7 +105,9 @@ input = {
Possible attributes:

- `id`: String ID of the item created.
- `amount`: Amount of items in the created stack
- `amount`: Amount of items in the created stack.

**Note:** `id` can also be a group. See [Item#Attributes#groups](/lua-api-item#groups) for more details.

#### `output`

Expand Down
6 changes: 5 additions & 1 deletion mods/default/blocks.lua
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,11 @@ mod:block {
mod:block {
id = "oak_planks",
name = "Oak Wood Planks",
tiles = "oak_planks.png"
tiles = "oak_planks.png",

groups = {
om_planks = 1
}
}

mod:block {
Expand Down
7 changes: 4 additions & 3 deletions mods/default/furnace.lua
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ mod:block {

size = {x = 1, y = 1},

filter = "group:om_fuel",
shift_destination = "inv_main,inv_hotbar",
}

Expand Down Expand Up @@ -183,12 +184,12 @@ mod:block {
end

if ticks_remaining == 0 and recipe and fuel_stack:amount() > 0 and
fuel_stack:item():is_fuel() and
fuel_stack:item():has_group("group:om_fuel") and
(output_stack:item():id() == 0 or output_stack:amount() == 0
or output_stack:item():id() == recipe:result():item():id()) then
data.inventory:set_stack(2, 0, fuel_stack:item():string_id(), fuel_stack:amount() - 1)
ticks_remaining = fuel_stack:item():burn_time()
current_burn_time = fuel_stack:item():burn_time()
ticks_remaining = fuel_stack:item():get_group_value("group:om_fuel")
current_burn_time = fuel_stack:item():get_group_value("group:om_fuel")
data.use_alt_tiles = true;
-- world:set_data(pos.x, pos.y, pos.z, 1)
elseif ticks_remaining > 0 then
Expand Down
12 changes: 8 additions & 4 deletions mods/default/items.lua
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,10 @@ mod:item {
id = "coal",
name = "Coal",
tiles = "coal.png",
is_fuel = true,
burn_time = 1600,

groups = {
om_fuel = 1600,
},
}

mod:item {
Expand All @@ -85,8 +87,10 @@ mod:item {
id = "charcoal",
name = "Charcoal",
tiles = "charcoal.png",
is_fuel = true,
burn_time = 1600,

groups = {
om_fuel = 1600,
},
}

mod:item {
Expand Down
4 changes: 2 additions & 2 deletions mods/default/recipes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ mod:crafting_recipe {
'#'
},

keys = {['#'] = "default:oak_planks"}
keys = {['#'] = "group:om_planks"}
}

-- Planks
Expand All @@ -536,7 +536,7 @@ mod:crafting_recipe {
"##",
"##"
},
keys = {["#"] = "default:oak_planks"}
keys = {["#"] = "group:om_planks"}
}

-- Furnace
Expand Down
7 changes: 7 additions & 0 deletions source/client/gui/AbstractInventoryWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,10 @@ void AbstractInventoryWidget::setShiftDestination(const std::string &shiftDestin
}
}

bool AbstractInventoryWidget::doItemMatchFilter(const Item &item) {
if (!m_filter.empty() && item.id() != 0)
return item.hasGroup(m_filter);

return true;
}

6 changes: 6 additions & 0 deletions source/client/gui/AbstractInventoryWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,14 @@ class AbstractInventoryWidget : public Widget {
void setShiftDestination(const std::string &shiftDestination);
void setShiftDestination(const std::vector<std::string> &shiftDestination) { m_shiftDestination = shiftDestination; }

const std::string &filter() const { return m_filter; }
void setFilter(const std::string &filter) { m_filter = filter; }
bool doItemMatchFilter(const Item &item);

protected:
std::vector<std::string> m_shiftDestination;

std::string m_filter;
};

#endif // ABSTRACTINVENTORYWIDGET_HPP_
2 changes: 1 addition & 1 deletion source/client/gui/InventoryWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void InventoryWidget::update() {
}

bool InventoryWidget::sendItemStackToDest(const ItemWidget *itemStack, AbstractInventoryWidget *dest) {
if (dest->receiveItemStack(itemStack, this)) {
if (dest->doItemMatchFilter(itemStack->stack().item()) && dest->receiveItemStack(itemStack, this)) {
if (dest != this)
m_inventory->clearStack(itemStack->x(), itemStack->y());

Expand Down
33 changes: 19 additions & 14 deletions source/client/gui/MouseItemWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,24 +76,28 @@ void MouseItemWidget::onEvent(const SDL_Event &event) {

void MouseItemWidget::leftClickBehaviour() {
if (m_currentInventoryWidget && m_currentInventoryWidget->currentItemWidget() && m_currentInventoryWidget->inventory()) {
ItemWidget *currentItemWidget = m_currentInventoryWidget->currentItemWidget();
if (!m_currentInventoryWidget->inventory()->isUnlimited())
swapItems(*currentItemWidget, m_currentInventoryWidget->isReadOnly());
else if (getStack().amount() == 0 && currentItemWidget->stack().amount() != 0)
setStack(currentItemWidget->stack().item().stringID(), 64);
if (m_currentInventoryWidget->doItemMatchFilter(m_inventory.getStack(0, 0).item())) {
ItemWidget *currentItemWidget = m_currentInventoryWidget->currentItemWidget();
if (!m_currentInventoryWidget->inventory()->isUnlimited())
swapItems(*currentItemWidget, m_currentInventoryWidget->isReadOnly());
else if (getStack().amount() == 0 && currentItemWidget->stack().amount() != 0)
setStack(currentItemWidget->stack().item().stringID(), 64);

m_currentInventoryWidget->sendUpdatePacket();
m_currentInventoryWidget->sendUpdatePacket();
}
}
}

void MouseItemWidget::rightClickBehaviour() {
if (m_currentInventoryWidget && m_currentInventoryWidget->currentItemWidget() && m_currentInventoryWidget->inventory()) {
if (!m_currentInventoryWidget->isReadOnly()) {
ItemWidget *currentItemWidget = m_currentInventoryWidget->currentItemWidget();
if (!m_currentInventoryWidget->inventory()->isUnlimited())
putItem(*currentItemWidget);
else if (getStack().amount() == 0 && currentItemWidget->stack().amount() != 0)
setStack(currentItemWidget->stack().item().stringID(), 1);
if (m_currentInventoryWidget->doItemMatchFilter(m_inventory.getStack(0, 0).item())) {
ItemWidget *currentItemWidget = m_currentInventoryWidget->currentItemWidget();
if (!m_currentInventoryWidget->inventory()->isUnlimited())
putItem(*currentItemWidget);
else if (getStack().amount() == 0 && currentItemWidget->stack().amount() != 0)
setStack(currentItemWidget->stack().item().stringID(), 1);
}

m_currentInventoryWidget->sendUpdatePacket();
}
Expand Down Expand Up @@ -167,14 +171,15 @@ void MouseItemWidget::draggingBehaviour(ItemWidget *newItemWidget) {

void MouseItemWidget::updateCurrentItem(ItemWidget *currentItemWidget) {
if (currentItemWidget) {
if (m_isDragging && currentItemWidget != m_currentItemWidget)
bool doItemMatchFilter = !m_currentInventoryWidget || m_currentInventoryWidget->doItemMatchFilter(m_draggedStack.item());
if (m_isDragging && currentItemWidget != m_currentItemWidget && doItemMatchFilter)
draggingBehaviour(currentItemWidget);

m_currentItemWidget = (currentItemWidget->stack().item().id()) ? currentItemWidget : nullptr;
m_tooltipText.setText(currentItemWidget->stack().item().label() + " [" + std::to_string(currentItemWidget->stack().item().id()) + "]");

if (currentItemWidget->stack().item().isFuel())
m_tooltipInfoText.setText("Burn time: " + std::to_string(currentItemWidget->stack().item().burnTime()) + " ticks");
if (currentItemWidget->stack().item().hasGroup("group:om_fuel"))
m_tooltipInfoText.setText("Burn time: " + std::to_string(currentItemWidget->stack().item().getGroupValue("group:om_fuel")) + " ticks");
else
m_tooltipInfoText.setText("");
}
Expand Down
7 changes: 4 additions & 3 deletions source/client/states/LuaGUIState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ void LuaGUIState::update() {
}
}

m_mouseItemWidget.updateCurrentItem(currentItemWidget);
m_mouseItemWidget.setCurrentInventoryWidget(m_currentInventoryWidget);
m_mouseItemWidget.updateCurrentItem(currentItemWidget);
}

void LuaGUIState::draw(gk::RenderTarget &target, gk::RenderStates states) const {
Expand Down Expand Up @@ -222,10 +222,10 @@ void LuaGUIState::loadTextButton(const std::string &, s32 x, s32 y, sf::Packet &
}

void LuaGUIState::loadInventoryWidget(const std::string &name, s32 x, s32 y, sf::Packet &packet) {
std::string inventory, shiftDestination;
std::string inventory, shiftDestination, filter;
u16 width, height;
u16 offset, count;
packet >> width >> height >> shiftDestination >> offset >> count >> inventory;
packet >> width >> height >> shiftDestination >> offset >> count >> inventory >> filter;

Inventory *widgetInventory = nullptr;
if (inventory == "player") {
Expand Down Expand Up @@ -270,6 +270,7 @@ void LuaGUIState::loadInventoryWidget(const std::string &name, s32 x, s32 y, sf:
inventoryWidget.setPosition(x, y);
inventoryWidget.init(*widgetInventory, offset, count);
inventoryWidget.setShiftDestination(shiftDestination);
inventoryWidget.setFilter(filter);
}
else {
DEBUG("ERROR: Inventory widget '" + name + "' is invalid");
Expand Down
8 changes: 4 additions & 4 deletions source/common/inventory/CraftingRecipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,17 @@ bool CraftingRecipe::checkMatch(const Inventory &inventory, int offsetX, int off
for (x = 0 ; x < m_pattern[y].size() ; ++x) {
itemFound = false;

std::string inventoryItem = inventory.getStack(offsetX + x, offsetY + y).item().stringID();
const Item &item = inventory.getStack(offsetX + x, offsetY + y).item();
if (m_pattern[y][x] == ' ') {
itemFound = (inventoryItem.empty() || inventoryItem == "_:air");
itemFound = (item.stringID().empty() || item.stringID() == "_:air");
}
else {
auto it = m_keys.find(m_pattern[y][x]);
if (it == m_keys.end())
throw EXCEPTION("Recipe error: Invalid key char(", (int)m_pattern[y][x], ")'");

for (const std::string &item : it->second) {
if (item == inventoryItem)
for (const std::string &itemID : it->second) {
if (itemID == item.stringID() || (itemID.substr(0, 6) == "group:" && item.hasGroup(itemID)))
itemFound = true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion source/common/inventory/Inventory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class Inventory : public ISerializable {
ItemStack &getStackRef(u16 x, u16 y) { return m_items.at(x + y * m_width); }
void setStack(u16 x, u16 y, const std::string &stringID, u16 amount = 1);
bool addStack(const std::string &stringID, u16 amount = 1, u16 offset = 0, u16 size = 0);
bool addStack2(const std::string &stringID, u16 amount = 1);
bool addStack2(const std::string &stringID, u16 amount = 1); // Needed for Lua
void clearStack(u16 x, u16 y);

void serialize(sf::Packet &packet) const override;
Expand Down
11 changes: 5 additions & 6 deletions source/common/inventory/Item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@
*
* =====================================================================================
*/
#include <SFML/Network/Packet.hpp>

#include "Item.hpp"
#include "NetworkUtils.hpp"

Item::Item(u32 id, const TilesDef &tiles, const std::string &stringID, const std::string &label) {
m_id = id;
Expand All @@ -37,12 +36,12 @@ Item::Item(u32 id, const TilesDef &tiles, const std::string &stringID, const std
}

void Item::serialize(sf::Packet &packet) const {
packet << m_id << m_stringID << m_label << m_isBlock << m_isFuel
<< m_burnTime << m_miningSpeed << m_harvestCapability << m_tiles;
packet << m_id << m_tiles << m_stringID << m_label << m_isBlock
<< m_miningSpeed << m_harvestCapability << m_groups;
}

void Item::deserialize(sf::Packet &packet) {
packet >> m_id >> m_stringID >> m_label >> m_isBlock >> m_isFuel
>> m_burnTime >> m_miningSpeed >> m_harvestCapability >> m_tiles;
packet >> m_id >> m_tiles >> m_stringID >> m_label >> m_isBlock
>> m_miningSpeed >> m_harvestCapability >> m_groups;
}

Loading