diff --git a/entities/entity.cpp b/entities/entity.cpp index 67909d1..49ce214 100644 --- a/entities/entity.cpp +++ b/entities/entity.cpp @@ -923,7 +923,22 @@ bool Entity::hass_craft_recipe(Ref craft_recipe) { return false; } +bool Entity::hass_craft_recipe_id(int id) { + for (int i = 0; i < _s_craft_recipes.size(); ++i) { + Ref cr = _s_craft_recipes.get(i); + + ERR_CONTINUE(!cr.is_valid()); + + if (cr->get_id() == id) { + return true; + } + } + + return false; +} void Entity::adds_craft_recipe(Ref craft_recipe) { + ERR_FAIL_COND(!craft_recipe.is_valid()); + if (hass_craft_recipe(craft_recipe)) return; @@ -931,7 +946,23 @@ void Entity::adds_craft_recipe(Ref craft_recipe) { emit_signal("scraft_recipe_added", this, craft_recipe); - ORPC(addc_craft_recipe, craft_recipe); + ORPC(addc_craft_recipe_id, craft_recipe->get_id()); +} +void Entity::adds_craft_recipe_id(int id) { + ERR_FAIL_COND(!EntityDataManager::get_instance()); + + if (hass_craft_recipe_id(id)) + return; + + Ref craft_recipe = EntityDataManager::get_instance()->get_craft_data(id); + + ERR_FAIL_COND(!craft_recipe.is_valid()); + + _s_craft_recipes.push_back(craft_recipe); + + emit_signal("scraft_recipe_added", this, craft_recipe); + + ORPC(addc_craft_recipe_id, id); } void Entity::removes_craft_recipe(Ref craft_recipe) { for (int i = 0; i < _s_craft_recipes.size(); ++i) { @@ -945,11 +976,38 @@ void Entity::removes_craft_recipe(Ref craft_recipe) { ORPC(removec_craft_recipe, craft_recipe); } +void Entity::removes_craft_recipe_id(int id) { + Ref craft_recipe; + + for (int i = 0; i < _s_craft_recipes.size(); ++i) { + craft_recipe = _s_craft_recipes.get(i); + + if (craft_recipe->get_id() == id) { + _s_craft_recipes.remove(i); + break; + } + } + + emit_signal("scraft_recipe_removed", this, craft_recipe); + + ORPC(removec_craft_recipe_id, id); +} Ref Entity::gets_craft_recipe(int index) { ERR_FAIL_INDEX_V(index, _s_craft_recipes.size(), Ref()); return _s_craft_recipes.get(index); } +Ref Entity::gets_craft_recipe_id(int id) { + for (int i = 0; i < _s_craft_recipes.size(); ++i) { + Ref craft_recipe = _s_craft_recipes.get(i); + + if (craft_recipe->get_id() == id) { + return craft_recipe; + } + } + + return Ref(); +} int Entity::gets_craft_recipe_count() { return _s_craft_recipes.size(); } @@ -963,6 +1021,19 @@ bool Entity::hasc_craft_recipe(Ref craft_recipe) { return false; } +bool Entity::hasc_craft_recipe_id(int id) { + for (int i = 0; i < _c_craft_recipes.size(); ++i) { + Ref cr = _c_craft_recipes.get(i); + + ERR_CONTINUE(!cr.is_valid()); + + if (cr->get_id() == id) { + return true; + } + } + + return false; +} void Entity::addc_craft_recipe(Ref craft_recipe) { if (hasc_craft_recipe(craft_recipe)) return; @@ -971,6 +1042,20 @@ void Entity::addc_craft_recipe(Ref craft_recipe) { emit_signal("ccraft_recipe_added", this, craft_recipe); } +void Entity::addc_craft_recipe_id(int id) { + ERR_FAIL_COND(!EntityDataManager::get_instance()); + + if (hasc_craft_recipe_id(id)) + return; + + Ref craft_recipe = EntityDataManager::get_instance()->get_craft_data(id); + + ERR_FAIL_COND(!craft_recipe.is_valid()); + + _c_craft_recipes.push_back(craft_recipe); + + emit_signal("ccraft_recipe_added", this, craft_recipe); +} void Entity::removec_craft_recipe(Ref craft_recipe) { for (int i = 0; i < _c_craft_recipes.size(); ++i) { if (_c_craft_recipes.get(i) == craft_recipe) { @@ -981,6 +1066,20 @@ void Entity::removec_craft_recipe(Ref craft_recipe) { emit_signal("ccraft_recipe_removed", this, craft_recipe); } +void Entity::removec_craft_recipe_id(int id) { + Ref craft_recipe; + + for (int i = 0; i < _c_craft_recipes.size(); ++i) { + craft_recipe = _c_craft_recipes.get(i); + + if (craft_recipe->get_id() == id) { + _c_craft_recipes.remove(i); + break; + } + } + + emit_signal("ccraft_recipe_removed", this, craft_recipe); +} Ref Entity::getc_craft_recipe(int index) { ERR_FAIL_INDEX_V(index, _c_craft_recipes.size(), Ref()); @@ -4503,8 +4602,8 @@ Entity::Entity() { SET_RPC_REMOTE("scraft"); - SET_RPC_REMOTE("addc_craft_recipe"); - SET_RPC_REMOTE("removec_craft_recipe"); + SET_RPC_REMOTE("addc_craft_recipe_id"); + SET_RPC_REMOTE("removec_craft_recipe_id"); //// SpellSystem //// @@ -5410,14 +5509,21 @@ void Entity::_bind_methods() { ClassDB::bind_method(D_METHOD("scraft", "id"), &Entity::scraft); ClassDB::bind_method(D_METHOD("hass_craft_recipe", "craft_recipe"), &Entity::hass_craft_recipe); + ClassDB::bind_method(D_METHOD("hass_craft_recipe_id", "id"), &Entity::hass_craft_recipe_id); ClassDB::bind_method(D_METHOD("adds_craft_recipe", "craft_recipe"), &Entity::adds_craft_recipe); + ClassDB::bind_method(D_METHOD("adds_craft_recipe_id", "id"), &Entity::adds_craft_recipe_id); ClassDB::bind_method(D_METHOD("removes_craft_recipe", "craft_recipe"), &Entity::removes_craft_recipe); - ClassDB::bind_method(D_METHOD("gets_craft_recipe", "craft_recipe"), &Entity::gets_craft_recipe); + ClassDB::bind_method(D_METHOD("removes_craft_recipe_id", "id"), &Entity::removes_craft_recipe_id); + ClassDB::bind_method(D_METHOD("gets_craft_recipe", "index"), &Entity::gets_craft_recipe); + ClassDB::bind_method(D_METHOD("gets_craft_recipe_id", "id"), &Entity::gets_craft_recipe_id); ClassDB::bind_method(D_METHOD("gets_craft_recipe_count"), &Entity::gets_craft_recipe_count); ClassDB::bind_method(D_METHOD("hasc_craft_recipe", "craft_recipe"), &Entity::hasc_craft_recipe); + ClassDB::bind_method(D_METHOD("hasc_craft_recipe_id", "id"), &Entity::hasc_craft_recipe_id); ClassDB::bind_method(D_METHOD("addc_craft_recipe", "craft_recipe"), &Entity::addc_craft_recipe); + ClassDB::bind_method(D_METHOD("addc_craft_recipe_id", "id"), &Entity::addc_craft_recipe_id); ClassDB::bind_method(D_METHOD("removec_craft_recipe", "craft_recipe"), &Entity::removec_craft_recipe); + ClassDB::bind_method(D_METHOD("removec_craft_recipe_id", "id"), &Entity::removec_craft_recipe_id); ClassDB::bind_method(D_METHOD("getc_craft_recipe", "craft_recipe"), &Entity::getc_craft_recipe); ClassDB::bind_method(D_METHOD("getc_craft_recipe_count"), &Entity::getc_craft_recipe_count); diff --git a/entities/entity.h b/entities/entity.h index 56799fd..64004dd 100644 --- a/entities/entity.h +++ b/entities/entity.h @@ -352,14 +352,21 @@ public: void scraft(int id); bool hass_craft_recipe(Ref craft_recipe); + bool hass_craft_recipe_id(int id); void adds_craft_recipe(Ref craft_recipe); + void adds_craft_recipe_id(int id); void removes_craft_recipe(Ref craft_recipe); + void removes_craft_recipe_id(int id); Ref gets_craft_recipe(int index); + Ref gets_craft_recipe_id(int id); int gets_craft_recipe_count(); bool hasc_craft_recipe(Ref craft_recipe); + bool hasc_craft_recipe_id(int id); void addc_craft_recipe(Ref craft_recipe); + void addc_craft_recipe_id(int id); void removec_craft_recipe(Ref craft_recipe); + void removec_craft_recipe_id(int id); Ref getc_craft_recipe(int index); int getc_craft_recipe_count(); diff --git a/inventory/bag.cpp b/inventory/bag.cpp index cd444e7..eb95857 100644 --- a/inventory/bag.cpp +++ b/inventory/bag.cpp @@ -214,6 +214,62 @@ bool Bag::is_overburdened() { return _bag_size < get_valid_item_count(); } +bool Bag::has_item(Ref item, int count) { + return call("_has_item", item, count); +} +bool Bag::_has_item(Ref item, int count) { + int c = 0; + + for (int i = 0; i < _items.size(); ++i) { + Ref ii = _items.get(i); + + if (ii.is_valid()) { + if (ii->get_item_template() == item) { + c += ii->get_stack_size(); + + if (c >= count) { + return true; + } + } + } + } + + return false; +} + +void Bag::remove_items(Ref item, int count) { + call("_remove_items", item, count); +} +void Bag::_remove_items(Ref item, int count) { + int c = count; + + for (int i = 0; i < _items.size(); ++i) { + Ref ii = _items.get(i); + + if (ii.is_valid()) { + if (ii->get_item_template() == item) { + int ss = ii->get_stack_size(); + + if (ss > c) { + ii->set_stack_size(ss - c); + + emit_signal("item_count_changed", Ref(this), ii, i); + return; + } else if (ss < c) { + c -= ii->get_stack_size(); + + remove_item(i); + } else if (ss == c) { + remove_item(i); + return; + } + + } + } + } +} + + Dictionary Bag::to_dict() { return call("_to_dict"); } @@ -282,6 +338,8 @@ void Bag::_bind_methods() { BIND_VMETHOD(MethodInfo("_set_size", PropertyInfo(Variant::INT, "size"))); BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::BOOL, "full"), "_is_full")); BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::BOOL, "overburdened"), "_is_overburdened")); + BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::BOOL, "has"), "_has_item", PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "ItemTemplate"), PropertyInfo(Variant::INT, "count"))); + BIND_VMETHOD(MethodInfo("_remove_items", PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "ItemTemplate"), PropertyInfo(Variant::INT, "count"))); ADD_SIGNAL(MethodInfo("item_added", PropertyInfo(Variant::OBJECT, "bag", PROPERTY_HINT_RESOURCE_TYPE, "Bag"), PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "ItemInstance"), PropertyInfo(Variant::INT, "slot_id"))); ADD_SIGNAL(MethodInfo("item_set", PropertyInfo(Variant::OBJECT, "bag", PROPERTY_HINT_RESOURCE_TYPE, "Bag"), PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "ItemInstance"), PropertyInfo(Variant::INT, "slot_id"))); @@ -313,6 +371,12 @@ void Bag::_bind_methods() { ClassDB::bind_method(D_METHOD("is_full"), &Bag::is_full); ClassDB::bind_method(D_METHOD("is_overburdened"), &Bag::is_overburdened); + ClassDB::bind_method(D_METHOD("has_item", "item", "count"), &Bag::has_item); + ClassDB::bind_method(D_METHOD("_has_item", "item", "count"), &Bag::_has_item); + + ClassDB::bind_method(D_METHOD("remove_items", "item", "count"), &Bag::remove_items); + ClassDB::bind_method(D_METHOD("_remove_items", "item", "count"), &Bag::_remove_items); + //Serialization BIND_VMETHOD(MethodInfo("_from_dict", PropertyInfo(Variant::DICTIONARY, "dict"))); BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::DICTIONARY, "dict"), "_to_dict")); diff --git a/inventory/bag.h b/inventory/bag.h index 670457d..3359994 100644 --- a/inventory/bag.h +++ b/inventory/bag.h @@ -6,7 +6,7 @@ #include "../item_enums.h" -class itemTemplate; +class ItemTemplate; class ItemInstance; class Bag : public Reference { @@ -32,6 +32,12 @@ public: bool is_full(); bool is_overburdened(); + + bool has_item(Ref item, int count); + bool _has_item(Ref item, int count); + + void remove_items(Ref item, int count); + void _remove_items(Ref item, int count); Dictionary to_dict(); void from_dict(const Dictionary &dict);