diff --git a/entities/entity.cpp b/entities/entity.cpp index ad535f1..80400b4 100644 --- a/entities/entity.cpp +++ b/entities/entity.cpp @@ -607,6 +607,30 @@ void Entity::_setup(Ref info) { sets_class_xp(info->get_class_xp()); sets_character_xp(info->get_character_xp()); + + if (EntityDataManager::get_instance()->get_allow_class_spell_learning()) { + Ref class_profile = ProfileManager::get_instance()->getc_player_profile()->get_class_profile(_s_entity_data->get_id()); + + if (class_profile.is_valid() && class_profile->has_custom_data("spells")) { + Vector spells = class_profile->get_custom_data("spells"); + + for (int i = 0; i < spells.size(); ++i) { + adds_spell_id(spells.get(i)); + } + } + } + + if (EntityDataManager::get_instance()->get_allow_class_recipe_learning()) { + Ref class_profile = ProfileManager::get_instance()->getc_player_profile()->get_class_profile(_s_entity_data->get_id()); + + if (class_profile.is_valid() && class_profile->has_custom_data("recipes")) { + Vector recipes = class_profile->get_custom_data("recipes"); + + for (int i = 0; i < recipes.size(); ++i) { + adds_craft_recipe_id(recipes.get(i)); + } + } + } } void Entity::setup_actionbars() { @@ -1466,6 +1490,32 @@ void Entity::adds_craft_recipe_id(int id) { _s_craft_recipes.push_back(craft_recipe); + if (EntityDataManager::get_instance()->get_allow_class_recipe_learning() && (_s_entity_player_type == EntityEnums::ENTITY_PLAYER_TYPE_PLAYER || gets_entity_player_type() == EntityEnums::ENTITY_PLAYER_TYPE_DISPLAY)) { + Ref class_profile = ProfileManager::get_instance()->getc_player_profile()->get_class_profile(_s_entity_data->get_id()); + + if (class_profile->has_custom_data("recipes")) { + Vector recipes = class_profile->get_custom_data("recipes"); + + bool found = false; + + for (int i = 0; i < recipes.size(); ++i) { + if (recipes[i] == id) { + found = true; + break; + } + } + + if (!found) { + recipes.push_back(id); + class_profile->set_custom_data("recipes", recipes); + } + } else { + Vector recipes; + recipes.push_back(id); + class_profile->set_custom_data("recipes", recipes); + } + } + emit_signal("scraft_recipe_added", this, craft_recipe); ORPC(addc_craft_recipe_id, id); @@ -2389,7 +2439,7 @@ void Entity::sclass_levelup(int value) { if (_s_class_level == EntityEnums::MAX_CLASS_LEVEL) return; - //_s_level += value; + _s_class_level += value; son_class_level_up(value); @@ -4404,12 +4454,48 @@ void Entity::adds_spell(Ref spell) { if (hass_spell(spell)) return; + int id = spell->get_id(); + _s_spells.push_back(spell); + if (EntityDataManager::get_instance()->get_allow_class_spell_learning() && (_s_entity_player_type == EntityEnums::ENTITY_PLAYER_TYPE_PLAYER || gets_entity_player_type() == EntityEnums::ENTITY_PLAYER_TYPE_DISPLAY)) { + Ref class_profile = ProfileManager::get_instance()->getc_player_profile()->get_class_profile(_s_entity_data->get_id()); + + if (class_profile->has_custom_data("spells")) { + Vector spells = class_profile->get_custom_data("spells"); + + bool found = false; + + for (int i = 0; i < spells.size(); ++i) { + if (spells[i] == id) { + found = true; + break; + } + } + + if (!found) { + spells.push_back(id); + class_profile->set_custom_data("spells", spells); + } + + } else { + Vector spells; + spells.push_back(id); + class_profile->set_custom_data("spells", spells); + } + } + emit_signal("sspell_added", this, spell); ORPCOBJ(addc_spell_rpc, spell->get_id(), addc_spell, spell); } +void Entity::adds_spell_id(int id) { + Ref spell = EntityDataManager::get_instance()->get_spell(id); + + ERR_FAIL_COND(!spell.is_valid()); + + adds_spell(spell); +} void Entity::removes_spell(Ref spell) { for (int i = 0; i < _s_spells.size(); ++i) { if (_s_spells.get(i) == spell) { @@ -7083,6 +7169,7 @@ void Entity::_bind_methods() { ClassDB::bind_method(D_METHOD("hass_spell", "spell"), &Entity::hass_spell); ClassDB::bind_method(D_METHOD("hass_spell_id", "id"), &Entity::hass_spell_id); ClassDB::bind_method(D_METHOD("adds_spell", "spell"), &Entity::adds_spell); + ClassDB::bind_method(D_METHOD("adds_spell_id", "id"), &Entity::adds_spell_id); ClassDB::bind_method(D_METHOD("removes_spell", "spell"), &Entity::removes_spell); ClassDB::bind_method(D_METHOD("gets_spell", "spell"), &Entity::gets_spell); ClassDB::bind_method(D_METHOD("gets_spell_count"), &Entity::gets_spell_count); diff --git a/entities/entity.h b/entities/entity.h index 926bc31..f456951 100644 --- a/entities/entity.h +++ b/entities/entity.h @@ -715,6 +715,7 @@ public: bool hass_spell(Ref spell); bool hass_spell_id(int id); void adds_spell(Ref spell); + void adds_spell_id(int id); void removes_spell(Ref spell); Ref gets_spell(int index); int gets_spell_count(); diff --git a/profiles/class_profile.cpp b/profiles/class_profile.cpp index c3e80b3..7167c3f 100644 --- a/profiles/class_profile.cpp +++ b/profiles/class_profile.cpp @@ -78,11 +78,32 @@ void ClassProfile::emit_change() { emit_signal("changed"); } -Dictionary ClassProfile::get_custom_data() { - return _custom_data; +bool ClassProfile::has_custom_data(const String &p_name) const { + return _custom_data.has(p_name); } -void ClassProfile::set_custom_data(const Dictionary &dict) { - _custom_data = dict; + +void ClassProfile::set_custom_data(const String &p_name, const Variant &p_value) { + if (p_value.get_type() == Variant::NIL) { + _custom_data.erase(p_name); + + emit_change(); + + return; + }; + + _custom_data[p_name] = p_value; + + emit_change(); +} + +Variant ClassProfile::get_custom_data(const String &p_name) const { + ERR_FAIL_COND_V(!_custom_data.has(p_name), Variant()); + + return _custom_data[p_name]; +} + +void ClassProfile::remove_custom_data(const String &p_name) { + _custom_data.erase(p_name); emit_change(); } @@ -178,7 +199,7 @@ void ClassProfile::_bind_methods() { ClassDB::bind_method(D_METHOD("get_level"), &ClassProfile::get_level); ClassDB::bind_method(D_METHOD("set_level", "value"), &ClassProfile::set_level); - ADD_PROPERTY(PropertyInfo(Variant::INT, "level"), "set_class_id", "get_level"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "level"), "set_level", "get_level"); ClassDB::bind_method(D_METHOD("get_xp"), &ClassProfile::get_xp); ClassDB::bind_method(D_METHOD("set_xp", "value"), &ClassProfile::set_xp); @@ -188,9 +209,10 @@ void ClassProfile::_bind_methods() { ClassDB::bind_method(D_METHOD("set_actionbar_locked", "value"), &ClassProfile::set_actionbar_locked); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "actionbar_locked"), "set_actionbar_locked", "get_actionbar_locked"); - ClassDB::bind_method(D_METHOD("get_custom_data"), &ClassProfile::get_custom_data); - ClassDB::bind_method(D_METHOD("set_custom_data", "value"), &ClassProfile::set_custom_data); - ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "custom_data"), "set_custom_data", "get_custom_data"); + ClassDB::bind_method(D_METHOD("has_custom_data", "name"), &ClassProfile::has_custom_data); + ClassDB::bind_method(D_METHOD("set_custom_data", "name", "value"), &ClassProfile::set_custom_data); + ClassDB::bind_method(D_METHOD("remove_custom_data", "name"), &ClassProfile::remove_custom_data); + ClassDB::bind_method(D_METHOD("get_custom_data", "name"), &ClassProfile::get_custom_data); ClassDB::bind_method(D_METHOD("get_input_profile"), &ClassProfile::get_input_profile); ClassDB::bind_method(D_METHOD("get_action_bar_profile"), &ClassProfile::get_action_bar_profile); diff --git a/profiles/class_profile.h b/profiles/class_profile.h index 9bbaf4f..a79025e 100644 --- a/profiles/class_profile.h +++ b/profiles/class_profile.h @@ -49,8 +49,10 @@ public: void emit_change(); - Dictionary get_custom_data(); - void set_custom_data(const Dictionary &dict); + bool has_custom_data(const String &p_name) const; + void set_custom_data(const String &p_name, const Variant &p_value); + void remove_custom_data(const String &p_name); + Variant get_custom_data(const String &p_name) const; Dictionary to_dict() const; void from_dict(const Dictionary &dict); diff --git a/singletons/entity_data_manager.cpp b/singletons/entity_data_manager.cpp index 6bce961..120c9ef 100644 --- a/singletons/entity_data_manager.cpp +++ b/singletons/entity_data_manager.cpp @@ -78,6 +78,20 @@ void EntityDataManager::set_use_global_class_level(const bool value) { _use_global_class_level = value; } +bool EntityDataManager::get_allow_class_spell_learning() const { + return _allow_class_spell_learning; +} +void EntityDataManager::set_allow_class_spell_learning(const bool value) { + _allow_class_spell_learning = value; +} + +bool EntityDataManager::get_allow_class_recipe_learning() const { + return _allow_class_recipe_learning; +} +void EntityDataManager::set_allow_class_recipe_learning(const bool value) { + _allow_class_recipe_learning = value; +} + Ref EntityDataManager::get_skill_for_armor_type(const int index) { ERR_FAIL_INDEX_V(index, ItemEnums::ARMOR_TYPE_MAX, Ref()); @@ -999,13 +1013,21 @@ void EntityDataManager::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "automatic_class_levelups"), "set_automatic_class_levelups", "get_automatic_class_levelups"); ClassDB::bind_method(D_METHOD("get_use_class_xp"), &EntityDataManager::get_use_class_xp); - ClassDB::bind_method(D_METHOD("set_use_class_xp", "load"), &EntityDataManager::set_use_class_xp); + ClassDB::bind_method(D_METHOD("set_use_class_xp", "value"), &EntityDataManager::set_use_class_xp); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_class_xp"), "set_use_class_xp", "get_use_class_xp"); ClassDB::bind_method(D_METHOD("get_use_global_class_level"), &EntityDataManager::get_use_global_class_level); - ClassDB::bind_method(D_METHOD("set_use_global_class_level", "load"), &EntityDataManager::set_use_global_class_level); + ClassDB::bind_method(D_METHOD("set_use_global_class_level", "value"), &EntityDataManager::set_use_global_class_level); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_global_class_level"), "set_use_global_class_level", "get_use_global_class_level"); + ClassDB::bind_method(D_METHOD("get_allow_class_spell_learning"), &EntityDataManager::get_allow_class_spell_learning); + ClassDB::bind_method(D_METHOD("set_allow_class_spell_learning", "value"), &EntityDataManager::set_allow_class_spell_learning); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_class_spell_learning"), "set_allow_class_spell_learning", "get_allow_class_spell_learning"); + + ClassDB::bind_method(D_METHOD("get_allow_class_recipe_learning"), &EntityDataManager::get_allow_class_recipe_learning); + ClassDB::bind_method(D_METHOD("set_allow_class_recipe_learning", "value"), &EntityDataManager::set_allow_class_recipe_learning); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_class_recipe_learning"), "set_allow_class_recipe_learning", "get_allow_class_recipe_learning"); + ClassDB::bind_method(D_METHOD("get_skill_for_armor_type", "index"), &EntityDataManager::get_skill_for_armor_type); ClassDB::bind_method(D_METHOD("set_skill_for_armor_type", "index", "aura"), &EntityDataManager::set_skill_for_armor_type); @@ -1159,6 +1181,8 @@ EntityDataManager::EntityDataManager() { _use_spell_points = GLOBAL_DEF("ess/spells/use_spell_points", false); _scale_spells_by_default = GLOBAL_DEF("ess/spells/scale_spells_by_default", false); + _allow_class_spell_learning = GLOBAL_DEF("ess/spells/allow_class_spell_learning", false); + _allow_class_recipe_learning = GLOBAL_DEF("ess/spells/allow_class_recipe_learning", false); _use_class_xp = GLOBAL_DEF("ess/level/use_class_xp", false); _automatic_class_levelups = GLOBAL_DEF("ess/level/automatic_class_levelups", false); diff --git a/singletons/entity_data_manager.h b/singletons/entity_data_manager.h index 962b0fa..02f1710 100644 --- a/singletons/entity_data_manager.h +++ b/singletons/entity_data_manager.h @@ -80,6 +80,12 @@ public: bool get_use_global_class_level() const; void set_use_global_class_level(const bool value); + bool get_allow_class_spell_learning() const; + void set_allow_class_spell_learning(const bool value); + + bool get_allow_class_recipe_learning() const; + void set_allow_class_recipe_learning(const bool value); + Ref get_skill_for_armor_type(const int index); void set_skill_for_armor_type(const int index, const Ref &aura); @@ -258,6 +264,8 @@ private: bool _use_class_xp; bool _automatic_class_levelups; bool _use_global_class_level; + bool _allow_class_spell_learning; + bool _allow_class_recipe_learning; }; #endif