#ifndef SPELL_H #define SPELL_H /*************************************************************************/ /* spell.h */ /*************************************************************************/ /* This file is part of: */ /* PANDEMONIUM ENGINE */ /* https://github.com/Relintai/pandemonium_engine */ /*************************************************************************/ /* Copyright (c) 2022-present Péter Magyar. */ /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "core/object/resource.h" #include "scene/resources/texture.h" #include "../../entities/entity.h" #include "../../entity_enums.h" #include "../../infos/aura_infos.h" #include "../../infos/spell_cast_info.h" #include "../../spell_enums.h" #include "spell_effect_visual.h" class Entity; class SpellCastInfo; class Spell; class CraftRecipe; class EntityResourceCostData; class EntitySkillData; class SpellDamageInfo; class SpellHealInfo; class AuraData; class AuraGroup; class AuraApplyInfo; class EntityResource; class Spell : public Resource { GDCLASS(Spell, Resource); public: enum TargetRelationType { TARGET_SELF = 1 << 0, TARGET_ENEMY = 1 << 1, TARGET_FRIENDLY = 1 << 2 }; enum SpellTargetType { SPELL_TARGET_TYPE_SELF, SPELL_TARGET_TYPE_TARGET, SPELL_TARGET_TYPE_AROUND, SPELL_TARGET_TYPE_FRONT, SPELL_TARGET_TYPE_AROUND_TARGET }; enum SpellAOETargetType { SPELL_AOE_TARGET_TYPE_CASTER, SPELL_AOE_TARGET_TYPE_TARGET, SPELL_AOE_TARGET_TYPE_GOUND_TARGET_SELECTION, SPELL_AOE_TARGET_TYPE_RANDOM }; public: int get_id() const; void set_id(const int value); int spell_type_get() const; void spell_type_set(const int value); SpellEnums::SpellCategory get_spell_category() const; void set_spell_category(const SpellEnums::SpellCategory value); bool get_hide_from_actionbar() const; void set_hide_from_actionbar(const bool value); float get_cooldown() const; void set_cooldown(const float value); SpellTargetType get_target_type() const; void set_target_type(const SpellTargetType value); TargetRelationType get_target_relation_type() const; void set_target_relation_type(const TargetRelationType value); int get_level() const; void set_level(const int value); int get_rank() const; void set_rank(const int value); bool get_scale_with_level() const; void set_scale_with_level(const bool value); Ref get_item_cost(); void set_item_cost(const Ref &value); Ref get_required_item(); void set_required_item(const Ref &value); Ref get_resource_cost(); void set_resource_cost(const Ref &value); Ref get_resource_give(); void set_resource_give(const Ref &value); bool get_global_cooldown_enabled() const; void set_global_cooldown_enabled(const bool value); bool get_is_local_spell() const; void set_is_local_spell(const bool value); Ref get_icon(); void set_icon(const Ref &value); String get_text_translation_key() const; void set_text_translation_key(const String &value); String get_text_description() const; void set_text_description(const String &value); Ref get_visual_spell_effects(); void set_visual_spell_effects(const Ref &value); Ref get_teaches_craft_recipe(); void set_teaches_craft_recipe(const Ref &value); //Spells cast on caster int spells_cast_on_caster_num_get() const; void spells_cast_on_caster_num_set(const int value); Ref spell_cast_on_caster_get(const int index); void spell_cast_on_caster_set(const int index, const Ref &spell); Vector spells_cast_on_caster_get(); void spells_cast_on_caster_set(const Vector &spells); //Spells cast on target int spells_cast_on_target_num_get() const; void spells_cast_on_target_num_set(const int value); Ref spell_cast_on_target_get(const int index); void spell_cast_on_target_set(const int index, const Ref &spell); Vector spells_cast_on_target_get(); void spells_cast_on_target_set(const Vector &target_aura_applys); //Spells cast On Learn int on_learn_cast_spells_num_get() const; void on_learn_cast_spells_num_set(const int value); Ref spell_cast_on_learn_get(const int index); void spell_cast_on_learn_set(const int index, const Ref &spell); Vector spells_cast_on_learn_get(); void spells_cast_on_learn_set(const Vector &spells); //Range bool range_get_enabled() const; void range_set_enabled(const bool value); float range_get() const; void range_set(const float value); bool cast_time_get_enabled() const; void cast_time_set_enabled(const bool value); float cast_time_get() const; void cast_time_set(const float value); //Delay bool projectile_get_use_time() const; void projectile_set_use_time(const bool value); float projectile_get_time() const; void projectile_set_time(const float value); bool projectile_get_use_speed() const; void projectile_set_use_speed(const bool value); float projectile_get_speed() const; void projectile_set_speed(const float value); Ref projectile_get_scene() const; void projectile_set_scene(const Ref &value); //Damage bool damage_get_enabled() const; void damage_set_enabled(const bool value); int damage_get_type() const; void damage_set_type(const int value); int damage_get_min() const; void damage_set_min(const int value); int damage_get_max() const; void damage_set_max(const int value); int damage_get_scale_stat() const; void damage_set_scale_stat(const int value); float damage_get_scale_coeff() const; void damage_set_scale_coeff(const float value); bool heal_get_enabled() const; void heal_set_enabled(const bool value); int heal_get_min() const; void heal_set_min(const int value); int heal_get_max() const; void heal_set_max(const int value); int heal_get_scale_stat() const; void heal_set_scale_stat(const int value); float heal_get_scale_coeff() const; void heal_set_scale_coeff(const float value); //Dispells bool dispell_get_enabled() const; void dispell_set_enabled(const bool value); int dispell_get_count_min() const; void dispell_set_count_min(const int value); int dispell_get_count_max() const; void dispell_set_count_max(const int value); int dispell_get_aura_types() const; void dispell_set_aura_types(const int value); //Target bool get_needs_target() const; void set_needs_target(const bool value); bool get_can_move_while_casting() const; void set_can_move_while_casting(const bool value); bool get_interrupt_enabled() const; void set_interrupt_enabled(const bool value); float get_interrupt_time() const; void set_interrupt_time(const float value); //AOE bool get_is_aoe() const; void set_is_aoe(const bool value); SpellAOETargetType get_aoe_target_type() const; void set_aoe_target_type(const SpellAOETargetType value); SpellEnums::ColliderType get_aoe_collider_type() const; void set_aoe_collider_type(const SpellEnums::ColliderType value); float get_aoe_radius() const; void set_aoe_radius(const float value); Vector3 get_aoe_box_extents() const; void set_aoe_box_extents(const Vector3 value); int get_spell_cooldown_mainpulation_data_count() const; void set_spell_cooldown_mainpulation_data_count(const int value); int get_training_cost() const; void set_training_cost(int value); Ref get_training_required_spell(); void set_training_required_spell(const Ref &spell); Ref get_training_required_skill(); void set_training_required_skill(const Ref &skill); int get_training_required_skill_level() const; void set_training_required_skill_level(const int value); //Auras bool aura_get_permanent() const; void aura_set_permanent(const bool value); float aura_get_time() const; void aura_set_time(const float value); Ref aura_get_aura_group(); void aura_set_aura_group(const Ref &value); bool aura_get_is_debuff() const; void aura_set_is_debuff(const bool value); float aura_get_tick() const; void aura_set_tick(const float value); SpellEnums::AuraType aura_get_aura_type() const; void aura_set_aura_type(const SpellEnums::AuraType value); bool aura_get_scale_with_level() const; void aura_set_scale_with_level(const bool value); String aura_get_text_translation_key() const; void aura_set_text_translation_key(const String &value); String aura_get_text_description() const; void aura_set_text_description(const String description); bool aura_get_hide() const; void aura_set_hide(const bool value); Ref aura_get_visual_spell_effects(); void aura_set_visual_spell_effects(const Ref &value); int aura_get_ability_scale_data_id() const; void aura_set_ability_scale_data_id(const int value); float aura_damage_get_scale_for_level(int level) const; float aura_heal_get_scale_for_level(int level) const; float aura_absorb_get_scale_for_level(int level) const; Ref aura_get_teaches_spell(); void aura_set_teaches_spell(const Ref &spell); //Damage bool aura_damage_get_enabled() const; void aura_damage_set_enabled(const bool value); int aura_damage_get_type() const; void aura_damage_set_type(const int value); int aura_damage_get_min() const; void aura_damage_set_min(const int value); int aura_damage_get_max() const; void aura_damage_set_max(const int value); bool aura_damage_get_can_crit() const; void aura_damage_set_can_crit(const bool value); void aura_damage_set(const int min, const int max, const bool can_crit); //Absorb bool aura_absorb_get_enabled() const; void aura_absorb_set_enabled(const bool value); int aura_absorb_damage_get_type() const; void aura_absorb_damage_set_type(const int value); int aura_absorb_get_min() const; void aura_absorb_set_min(const int value); int aura_absorb_get_max() const; void aura_absorb_set_max(const int value); //Heal bool aura_heal_get_enabled() const; void aura_heal_set_enabled(const bool value); int aura_heal_get_min() const; void aura_heal_set_min(const int value); int aura_heal_get_max() const; void aura_heal_set_max(const int value); bool aura_heal_get_can_crit() const; void aura_heal_set_can_crit(const bool value); void aura_heal_set(const int min, const int max, const bool can_crit); //Dispells bool aura_dispell_get_enabled() const; void aura_dispell_set_enabled(const bool value); int aura_dispell_get_count_min() const; void aura_dispell_set_count_min(const int value); int aura_dispell_get_count_max() const; void aura_dispell_set_count_max(const int value); int aura_dispell_get_aura_types() const; void aura_dispell_set_aura_types(const int value); //Resources Ref aura_get_resource_cost(); void aura_set_resource_cost(const Ref &value); Ref aura_get_resource_give(); void aura_set_resource_give(const Ref &value); Ref aura_damage_get_scaling_curve() { return _aura_damage_scaling_curve; } void aura_damage_set_scaling_curve(const Ref &curve) { _aura_damage_scaling_curve = curve; } Ref aura_heal_get_scaling_curve() { return _aura_heal_scaling_curve; } void aura_heal_set_scaling_curve(const Ref &curve) { _aura_heal_scaling_curve = curve; } Ref aura_absorb_get_scaling_curve() { return _aura_absorb_scaling_curve; } void aura_absorb_set_scaling_curve(const Ref &curve) { _aura_absorb_scaling_curve = curve; } //states int aura_get_add_states() const { return _aura_add_states; } void aura_set_add_states(const int value) { _aura_add_states = value; } int aura_get_remove_effects_with_states() const { return _aura_remove_effects_with_states; } void aura_set_remove_effects_with_states(const int value) { _aura_remove_effects_with_states = value; } int aura_get_supress_states() const { return _aura_supress_states; } void aura_set_supress_states(const int value) { _aura_supress_states = value; } //DiminishingReturns bool aura_diminishing_return_enabled_get() const; void aura_diminishing_return_enabled_set(const bool value); int aura_diminishing_return_category_get() const; void aura_diminishing_return_category_set(const int value); //Triggers int aura_trigger_get_count() const; void aura_trigger_set_count(const int count); SpellEnums::TriggerNotificationType aura_trigger_get_notification_type(const int index) const; void aura_trigger_set_notification_type(const int index, const SpellEnums::TriggerNotificationType value); int aura_trigger_get_notification_data(const int index) const; void aura_trigger_set_notification_data(const int index, const int value); SpellEnums::TriggerType aura_trigger_get_trigger_type(const int index) const; void aura_trigger_set_trigger_type(const int index, const SpellEnums::TriggerType value); float aura_trigger_get_trigger_type_data(const int index) const; void aura_trigger_set_trigger_type_data(const int index, const float value); Ref aura_trigger_get_spell(const int index) const; void aura_trigger_set_spell(const int index, const Ref &value); //Talent Ref aura_get_talent_required_talent() const; void aura_set_talent_required_talent(const Ref rank); Ref aura_get_talent_required_spell() const; void aura_set_talent_required_spell(const Ref spell); //AuraStatAttributes int aura_stat_attribute_get_count() const; void aura_stat_attribute_set_count(int count); int aura_stat_attribute_get_stat(int index) const; void aura_stat_attribute_set_stat(int index, const int value); float aura_stat_attribute_get_base_mod(int index) const; void aura_stat_attribute_set_base_mod(int index, float value); float aura_stat_attribute_get_bonus_mod(int index) const; void aura_stat_attribute_set_bonus_mod(int index, float value); float aura_stat_attribute_get_percent_mod(int index) const; void aura_stat_attribute_set_percent_mod(int index, float value); //// Spell Script //// float PLAYER_HIT_RADIUS; //Commands, c++ only void cast_starts_simple(Entity *caster, float spell_scale); void cast_interrupts_simple(Entity *caster); void cast_starts_triggered_simple(Entity *caster); void aura_sapply_simple(Entity *caster, Entity *target, float spell_scale); //Commands void cast_starts(Ref info); void cast_starts_triggered(Ref info); void cast_interrupts(Ref info); void cast_finishs(Ref info); void aura_sapply(Ref info); void aura_sdeapply(Ref info); void aura_sadd(Ref aura); void aura_sremove(Ref aura); void aura_removes_expired(Ref aura); void aura_removes_dispell(Ref aura); void aura_supdate(Ref aura, float delta); //eventhandlers void son_cast_player_moved(Ref info); void son_cast_damage_received(Ref info); void son_spell_hit(Ref info); void son_physics_process(Ref info, float delta); void notification_saura(int what, Ref data); void notification_sheal(int what, Ref aura, Ref data); void notification_aura_scast(int what, Ref aura, Ref info); void notification_sdamage(int what, Ref aura, Ref data); void son_remove(Ref aura); void son_remove_expired(Ref aura); void son_remove_dispell(Ref aura); void notification_sdeath(Ref data); void notification_scooldown_added(Ref data, int id, float value); void notification_scooldown_removed(Ref data, int id, float value); void notification_scategory_cooldown_added(Ref data, int id, float value); void notification_scategory_cooldown_removed(Ref data, int id, float value); void notification_sgcd_started(Ref data, float gcd); void notification_sgcd_finished(Ref data); void son_physics_process_aura(Ref data); void notification_sxp_gained(Ref data, int value); void notification_slevel_up(Ref data, int value); void notification_sentity_resource_added(Ref data, Ref resource); void notification_sentity_resource_removed(Ref data, Ref resource); //Clientside Event Handlers void notification_scast(int what, Ref info); void notification_ccast(int what, Ref info); void notification_caura(int what, Ref data); void notification_cheal(int what, Ref aura, Ref data); void notification_aura_ccast(int what, Ref aura, Ref info); void notification_cdamage(int what, Ref aura, Ref data); void notification_cdeath(Ref data); void notification_ccooldown_added(Ref data, int id, float value); void notification_ccooldown_removed(Ref data, int id, float value); void notification_ccategory_cooldown_added(Ref data, int id, float value); void notification_ccategory_cooldown_removed(Ref data, int id, float value); void notification_cgcd_started(Ref data, float gcd); void notification_cgcd_finished(Ref data); void notification_cxp_gained(Ref data, int value); void notification_clevel_up(Ref data, int value); void notification_centity_resource_added(Ref data, Ref resource); void notification_centity_resource_removed(Ref data, Ref resource); //Equipment bool equip_should_deny(Ref data, int equip_slot, Ref item); void equip_son_success(Ref data, int equip_slot, Ref item, Ref old_item, int bag_slot); void equip_son_fail(Ref data, int equip_slot, Ref item, Ref old_item, int bag_slot); void equip_con_success(Ref data, int equip_slot, Ref item, Ref old_item, int bag_slot); void equip_con_fail(Ref data, int equip_slot, Ref item, Ref old_item, int bag_slot); //Calculations / Queries void calculate_initial_damage(Ref data); void handle_spell_damage(Ref data); void calculate_initial_heal(Ref data); void handle_spell_heal(Ref data); void handle_projectile(Ref info); void handle_effect(Ref info); void handle_gcd(Ref info); void handle_cooldown(Ref info); void setup_aura_data(Ref data, Ref info); void aura_sapply_passives_damage_receive(Ref info); void aura_sapply_passives_damage_deal(Ref info); void aura_calculate_initial_damage(Ref aura_data, Ref info); void handle_aura_damage(Ref aura_data, Ref info); void aura_sapply_passives_heal_receive(Ref info); void aura_sapply_passives_heal_deal(Ref info); void aura_calculate_initial_heal(Ref aura_data, Ref info); void handle_aura_heal(Ref aura_data, Ref info); _FORCE_INLINE_ bool is_aura() const { return _aura_permanent || (_aura_time > CMP_EPSILON); } _FORCE_INLINE_ bool aura_is_talent() const { return _aura_type == SpellEnums::AURA_TYPE_TALENT; } String get_name_translated() const; String get_description(const int class_level, const int character_level); String _get_description(const int class_level, const int character_level); String aura_get_name_translated() const; String aura_get_description(const int class_level, const int character_level); String _aura_get_description(const int class_level, const int character_level); Spell(); ~Spell(); protected: virtual void _cast_starts(Ref info); virtual void _cast_finishs(Ref info); virtual void _son_cast_player_moved(Ref info); virtual void _son_spell_hit(Ref info); virtual void _calculate_initial_damage(Ref data); virtual void _handle_spell_damage(Ref data); virtual void _calculate_initial_heal(Ref data); virtual void _handle_spell_heal(Ref data); virtual void _handle_projectile(Ref info); virtual void _handle_effect(Ref info); virtual void _aura_sapply(Ref info); virtual void _aura_sdeapply(Ref info); virtual void _aura_sadd(Ref aura); virtual void _aura_sremove(Ref aura); virtual void _aura_removes_expired(Ref aura); virtual void _aura_removes_dispell(Ref aura); virtual void _aura_supdate(Ref aura, float delta); virtual void _setup_aura_data(Ref data, Ref info); virtual void _aura_sapply_passives_damage_receive(Ref info); virtual void _aura_sapply_passives_damage_deal(Ref info); virtual void _aura_calculate_initial_damage(Ref aura_data, Ref info); virtual void _handle_aura_damage(Ref aura_data, Ref info); virtual void _aura_sapply_passives_heal_receive(Ref info); virtual void _aura_sapply_passives_heal_deal(Ref info); virtual void _aura_calculate_initial_heal(Ref aura_data, Ref info); virtual void _handle_aura_heal(Ref aura_data, Ref info); void _validate_property(PropertyInfo &property) const; static void _bind_methods(); protected: struct AuraTriggerData { SpellEnums::TriggerNotificationType notification_type; int notification_data; SpellEnums::TriggerType trigger_type; float trigger_type_data; Ref spell; AuraTriggerData() { notification_type = SpellEnums::TRIGGER_NOTIFICATION_TYPE_AURA; trigger_type = SpellEnums::TRIGGER_TYPE_NONE; notification_data = 0; trigger_type_data = 0; } }; struct AuraStatAttribute { int stat; float base_mod; float bonus_mod; float percent_mod; AuraStatAttribute() { stat = 0; base_mod = 0; bonus_mod = 0; percent_mod = 0; } }; private: enum { MAX_AURA_STATS = 5, //Increase if necessary, should be enough for now MAX_TRIGGER_DATA = 5, }; int _id; int _spell_type; SpellEnums::SpellCategory _spell_category; bool _hide_from_actionbar; float _cooldown; SpellTargetType _target_type; TargetRelationType _target_relation_type; Vector> _spells_cast_on_caster; Vector> _spells_cast_on_target; Vector> _on_learn_cast_spells; int _level; int _rank; bool _scale_with_level; Ref _item_cost; Ref _required_item; Ref _resource_cost; Ref _resource_give; bool _global_cooldown_enabled; bool _is_local_spell; Ref _icon; String _text_translation_key; String _text_description; Ref _visual_spell_effects; Ref _teaches_craft_recipe; bool _range_enabled; float _range; //Delay bool _projectile_use_time; float _projectile_time; bool _projectile_use_speed; float _projectile_speed; Ref _projectile_scene; bool _damage_enabled; int _damage_type; int _damage_min; int _damage_max; int _damage_scale_stat; float _damage_scale_coeff; bool _heal_enabled; int _heal_min; int _heal_max; int _heal_scale_stat; float _heal_scale_coeff; bool _dispell_enabled; int _dispell_count_min; int _dispell_count_max; int _dispell_aura_types; bool _cast_time_enabled; float _cast_time; bool _needs_target; bool _can_move_while_casting; bool _interrupt_enabled; float _interrupt_time; bool _is_aoe; SpellAOETargetType _aoe_targetType; SpellEnums::ColliderType _aoe_colliderType; float _aoe_radius; Vector3 _aoe_box_extents; int _spell_cooldown_mainpulation_data_count; int _training_cost; Ref _training_required_spell; Ref _training_required_skill; int _training_required_skill_level; //Aura bool _aura_permanent; float _aura_time; float _aura_tick; Ref _aura_group; SpellEnums::AuraType _aura_type; bool _aura_is_debuff; bool _aura_hide; Ref _aura_teaches_spell; String _aura_text_translation_key; String _aura_text_description; int _aura_ability_scale_data_id; bool _aura_scale_with_level; Ref _aura_visual_spell_effects; bool _aura_damage_enabled; int _aura_damage_type; int _aura_damage_min; int _aura_damage_max; bool _aura_damage_can_crit; Ref _aura_damage_scaling_curve; bool _aura_absorb_enabled; int _aura_absorb_damage_type; int _aura_absorb_min; int _aura_absorb_max; Ref _aura_absorb_scaling_curve; bool _aura_heal_enabled; int _aura_heal_min; int _aura_heal_max; bool _aura_heal_can_crit; Ref _aura_heal_scaling_curve; bool _aura_dispell_enabled; int _aura_dispell_count_min; int _aura_dispell_count_max; int _aura_dispell_aura_types; Ref _aura_resource_cost; Ref _aura_resource_give; int _aura_add_states; int _aura_remove_effects_with_states; int _aura_supress_states; int _aura_trigger_count; AuraTriggerData _aura_trigger_datas[MAX_TRIGGER_DATA]; int _aura_stat_attribute_count; AuraStatAttribute _aura_stat_attributes[MAX_AURA_STATS]; bool _aura_diminishing_return_enabled; int _aura_diminishing_return_category; //Talent Ref _aura_talent_required_talent; Ref _aura_talent_required_spell; }; VARIANT_ENUM_CAST(Spell::TargetRelationType); VARIANT_ENUM_CAST(Spell::SpellTargetType); VARIANT_ENUM_CAST(Spell::SpellAOETargetType); #endif