Repository: Relintai/entity_spell_system Branch: master Commit: 3c240ff2b252 Files: 243 Total size: 1.5 MB Directory structure: gitextract_12vn9isv/ ├── .gitignore ├── LICENSE ├── README.md ├── SCsub ├── config.py ├── data/ │ ├── atlases/ │ │ ├── character_atlas.cpp │ │ ├── character_atlas.h │ │ ├── character_atlas_entry.cpp │ │ └── character_atlas_entry.h │ ├── auras/ │ │ ├── aura_group.cpp │ │ └── aura_group.h │ ├── items/ │ │ ├── craft_recipe.cpp │ │ ├── craft_recipe.h │ │ ├── craft_recipe_helper.cpp │ │ ├── craft_recipe_helper.h │ │ ├── equipment_data.cpp │ │ ├── equipment_data.h │ │ ├── item_instance.cpp │ │ ├── item_instance.h │ │ ├── item_template.cpp │ │ ├── item_template.h │ │ ├── model_visual.cpp │ │ ├── model_visual.h │ │ ├── model_visual_entry.cpp │ │ └── model_visual_entry.h │ ├── loot/ │ │ ├── loot_data_base.cpp │ │ └── loot_data_base.h │ ├── species/ │ │ ├── entity_species_data.cpp │ │ ├── entity_species_data.h │ │ ├── species_instance.cpp │ │ ├── species_instance.h │ │ ├── species_model_data.cpp │ │ └── species_model_data.h │ └── spells/ │ ├── spell.cpp │ ├── spell.h │ ├── spell_cooldown_manipulation_data.cpp │ ├── spell_cooldown_manipulation_data.h │ ├── spell_effect_visual.cpp │ ├── spell_effect_visual.h │ ├── spell_effect_visual_simple.cpp │ └── spell_effect_visual_simple.h ├── database/ │ ├── ess_resource_db.cpp │ ├── ess_resource_db.h │ ├── ess_resource_db_folders.cpp │ ├── ess_resource_db_folders.h │ ├── ess_resource_db_map.cpp │ ├── ess_resource_db_map.h │ ├── ess_resource_db_static.cpp │ └── ess_resource_db_static.h ├── defines.h ├── doc_classes/ │ ├── AIFormation.xml │ ├── ActionBarButtonEntry.xml │ ├── ActionBarEntry.xml │ ├── ActionBarProfile.xml │ ├── AuraApplyInfo.xml │ ├── AuraData.xml │ ├── AuraGroup.xml │ ├── Bag.xml │ ├── CharacterAtlas.xml │ ├── CharacterAtlasEntry.xml │ ├── CharacterBones.xml │ ├── CharacterSkeleton2D.xml │ ├── CharacterSkeleton3D.xml │ ├── CharacterSpec.xml │ ├── ClassProfile.xml │ ├── ComplexLevelStatData.xml │ ├── CraftRecipe.xml │ ├── CraftRecipeHelper.xml │ ├── ESDragAndDrop.xml │ ├── ESS.xml │ ├── ESSEntitySpawner.xml │ ├── ESSMaterialCache.xml │ ├── ESSMaterialCachePCM.xml │ ├── ESSResourceDB.xml │ ├── ESSResourceDBFolders.xml │ ├── ESSResourceDBMap.xml │ ├── ESSResourceDBStatic.xml │ ├── Entity.xml │ ├── EntityAI.xml │ ├── EntityClassData.xml │ ├── EntityCreateInfo.xml │ ├── EntityData.xml │ ├── EntityDataContainer.xml │ ├── EntityEnums.xml │ ├── EntityResource.xml │ ├── EntityResourceCostData.xml │ ├── EntityResourceCostDataHealth.xml │ ├── EntityResourceCostDataResource.xml │ ├── EntityResourceHealth.xml │ ├── EntityResourceSpeed.xml │ ├── EntitySkill.xml │ ├── EntitySkillData.xml │ ├── EntitySpeciesData.xml │ ├── EquipmentData.xml │ ├── InputProfile.xml │ ├── InputProfileModifier.xml │ ├── InputProfileModifierEntry.xml │ ├── ItemContainerData.xml │ ├── ItemContainerDataEntry.xml │ ├── ItemEnums.xml │ ├── ItemInstance.xml │ ├── ItemTemplate.xml │ ├── LevelStatData.xml │ ├── LootDataBase.xml │ ├── ModelVisual.xml │ ├── ModelVisualEntry.xml │ ├── PlayerProfile.xml │ ├── ProfileManager.xml │ ├── PropDataEntity.xml │ ├── SimpleLevelStatData.xml │ ├── SkeletonModelEntry.xml │ ├── SpeciesInstance.xml │ ├── SpeciesModelData.xml │ ├── Spell.xml │ ├── SpellCastInfo.xml │ ├── SpellCooldownManipulationData.xml │ ├── SpellDamageInfo.xml │ ├── SpellEffectVisual.xml │ ├── SpellEffectVisualSimple.xml │ ├── SpellEnums.xml │ ├── SpellFollowProjectile3D.xml │ ├── SpellHealInfo.xml │ ├── StatData.xml │ ├── VendorItemData.xml │ └── VendorItemDataEntry.xml ├── drag_and_drop/ │ ├── es_drag_and_drop.cpp │ └── es_drag_and_drop.h ├── editor/ │ ├── ess_editor_plugin.cpp │ └── ess_editor_plugin.h ├── entities/ │ ├── ai/ │ │ ├── entity_ai.cpp │ │ └── entity_ai.h │ ├── auras/ │ │ ├── aura_data.cpp │ │ └── aura_data.h │ ├── data/ │ │ ├── character_spec.cpp │ │ ├── character_spec.h │ │ ├── entity_class_data.cpp │ │ ├── entity_class_data.h │ │ ├── entity_data.cpp │ │ ├── entity_data.h │ │ ├── entity_data_container.cpp │ │ ├── entity_data_container.h │ │ ├── item_container_data.cpp │ │ ├── item_container_data.h │ │ ├── item_container_data_entry.cpp │ │ ├── item_container_data_entry.h │ │ ├── vendor_item_data.cpp │ │ ├── vendor_item_data.h │ │ ├── vendor_item_data_entry.cpp │ │ └── vendor_item_data_entry.h │ ├── entity.cpp │ ├── entity.h │ ├── resources/ │ │ ├── entity_resource.cpp │ │ ├── entity_resource.h │ │ ├── entity_resource_cost_data.cpp │ │ ├── entity_resource_cost_data.h │ │ ├── entity_resource_cost_data_health.cpp │ │ ├── entity_resource_cost_data_health.h │ │ ├── entity_resource_cost_data_resource.cpp │ │ ├── entity_resource_cost_data_resource.h │ │ ├── entity_resource_health.cpp │ │ ├── entity_resource_health.h │ │ ├── entity_resource_speed.cpp │ │ └── entity_resource_speed.h │ ├── skills/ │ │ ├── entity_skill.cpp │ │ ├── entity_skill.h │ │ ├── entity_skill_data.cpp │ │ └── entity_skill_data.h │ └── stats/ │ ├── complex_level_stat_data.cpp │ ├── complex_level_stat_data.h │ ├── level_stat_data.cpp │ ├── level_stat_data.h │ ├── simple_level_stat_data.cpp │ ├── simple_level_stat_data.h │ ├── stat_data.cpp │ └── stat_data.h ├── entity_enums.cpp ├── entity_enums.h ├── formations/ │ ├── ai_formation.cpp │ └── ai_formation.h ├── infos/ │ ├── aura_infos.cpp │ ├── aura_infos.h │ ├── spell_cast_info.cpp │ └── spell_cast_info.h ├── inventory/ │ ├── bag.cpp │ ├── bag.h │ ├── grid_bag.cpp │ ├── grid_bag.h │ ├── inventory.cpp │ ├── inventory.h │ ├── normal_bag.cpp │ └── normal_bag.h ├── item_enums.cpp ├── item_enums.h ├── material_cache/ │ ├── ess_material_cache.cpp │ ├── ess_material_cache.h │ ├── ess_material_cache_pcm.cpp │ └── ess_material_cache_pcm.h ├── pipelines/ │ ├── spell_damage_info.cpp │ ├── spell_damage_info.h │ ├── spell_heal_info.cpp │ └── spell_heal_info.h ├── profiles/ │ ├── actionbar/ │ │ ├── action_bar_button_entry.cpp │ │ ├── action_bar_button_entry.h │ │ ├── action_bar_entry.cpp │ │ ├── action_bar_entry.h │ │ ├── action_bar_profile.cpp │ │ └── action_bar_profile.h │ ├── class_profile.cpp │ ├── class_profile.h │ ├── input/ │ │ ├── input_profile.cpp │ │ ├── input_profile.h │ │ ├── input_profile_modifier.cpp │ │ ├── input_profile_modifier.h │ │ ├── input_profile_modifier_entry.cpp │ │ └── input_profile_modifier_entry.h │ ├── player_profile.cpp │ └── player_profile.h ├── projectiles/ │ └── 3d/ │ ├── spell_follow_projectile_3d.cpp │ └── spell_follow_projectile_3d.h ├── props/ │ ├── prop_data_entity.cpp │ └── prop_data_entity.h ├── register_types.cpp ├── register_types.h ├── singletons/ │ ├── ess.cpp │ ├── ess.h │ ├── profile_manager.cpp │ └── profile_manager.h ├── skeleton/ │ ├── character_bones.cpp │ ├── character_bones.h │ ├── character_skeleton_2d.cpp │ ├── character_skeleton_2d.h │ ├── character_skeleton_3d.cpp │ ├── character_skeleton_3d.h │ ├── entity_skeleton_data.cpp │ ├── entity_skeleton_data.h │ ├── skeleton_model_entry.cpp │ └── skeleton_model_entry.h ├── spawners/ │ ├── ess_entity_spawner.cpp │ └── ess_entity_spawner.h ├── spell_enums.cpp ├── spell_enums.h └── utility/ ├── entity_create_info.cpp └── entity_create_info.h ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .import *.d *.o *.meta *.obj *.pyc *.bc *.os ================================================ FILE: LICENSE ================================================ Copyright (c) 2019-2022 Péter Magyar 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. ================================================ FILE: README.md ================================================ # Entity Spell System An entity and spell system for the GODOT Engine, that is usable for both 2d, and 3d games. The main purpose of this module is to handle spells, auras, and most entity-related things like spawning, items, inventory, containers, vendors, interaction, targeting, equipment (+ visuals), loot, crafting, talents, pets, npcs, etc ... The module supports networking. It is designed to be authoritative, so players shouldn't be able to cheat by design. It is a c++ engine module, which means you will need to compile it into godot. (See compiling) ## Godot Version Support This branch tries to follow godot's master branch (as much as I have time). For different godot versions look at the other branches. Status for this branch: Update for 4.0 is still work in progress. Godot's virtual method binding rework hit this module extremely hard, to the point where I'm seriously considering reworking most of the virtuals to use a `_notification()`-like interface. ## Project setup tl;dr ### First You need to create an `ESSResourceDB` resource somewhere in you project. (Or alloocate it dynamically.) Now you can either: -Go to `ProjectSettings->Ess->Data`, and set the `ess_resource_db_path` property also make sure that `automatic_load` is on. -Or you can load it yourself and set it into the `ESS` singleton either using the `resource_db` property. ### Second You need to add an `ESSEntitySpawner` somewhere into your SceneTree. I recommend that you create an autoload for it. This is where you have to implement your spawning logic. ### What the module doesn't cover Movement, and controls. Unfortunately, there isn't a one-stop-shop solution for movement, especially if we throw networking into the mix, and the same is true for targeting. This means that this module cannot really do much in this regard, but it will give you as much help to set everything up as possible. ## Optional Dependencies Mesh Data Resource https://github.com/Relintai/mesh_data_resource.git Adds mesh (MeshDataResource) support to ModelVisuals. ## Pre-built binaries You can grab a pre-built editor binary from the [Broken Seals](https://github.com/Relintai/broken_seals/releases) repo, should you want to. It contains all my modules. ## Overview The module provides a huge number of script callbacks, usually as virtual methods they usually start with an underscore. Do not call methods with underscores, all of them has a normal counterpart, always call that. For example entity has `crafts(int id)` and `_crafts(int id)` (virtual). Always use `crafts(int id)`, it will call `_crafts(int id)`. For networked classes, every variable is broken up into clientside, and serverside. This makes it easier to develop games that can also run locally, with less overhead and simpler logic. E.g. this makes it easy to use the visibility system even when you play locally on the server, because you just use the clientside variables, and your logic will work the same way. ## Settings Entity and spell system comes with quite a few settings, you can find these under `ProjectSettings->Ess`. ## Singletons The module contains 2 singletons. `ESS`, and `ProfileManager`. Both are accessible from scripts. ### The ESS singleton Contains the active `ESSResourceDB` instance, and for convenience a reference to the active `ESSEntitySpawner` instance. Also loads/handles/processes all of the entity and spell system related ProjectSettings, so if you need any ESS related value from ProjectSettings, don't query it directly, get it from this singleton. Customizable enums values are preprocessed, and you usually have multiple ways of getting them. ### The ProfileManager singleton Contains methods to easily load/save/handle `PlayerProfile`s. #### PlayerProfile Contains player-related data, most notably `ClassProfile`s. #### ClassProfile Contains class-related data, most notably `ActionBarProfile`s, and `InputProfiles`. #### ActionBarProfile Contains the data for a set of actionbars. #### InputProfileswd Contains the keybind data for a class. ## Enums ESS needs lots of enums to work, and to reduce complexity with includes they ended up in a few separate classes. I'm still in the process of converting these to be customizable (`ESS` singleton / ProjectSettings). (Only the ones that worth it will be converted.) ### EntityEnums Contains Entity-related enums, like AIStates, skeleton attach points, entity flags, immunity flags, state flags. ### ItemEnums Contains item-related enums, like rarity, armor type, item types. ### SpellEnums Contains spell-related enums, like aura types, damage types, spell categories, spell types, trigger types, and quite a few notification constants. ### Customizable enums Open `ProjectSettings`, and then go to `ESS/Enums`. All of the string properties are customizable enums. These require a comma-separated list. They are essentially a godot comma separated property hint enum string. They all have defaults. Fer example: If you want you game to work with the following stats: Agility,Intellect,Crit,Weapon Damage,Stamina and you want Agility,Intellect,Stamina as you main stats. Firstly you want to put you main stats at the beginning, because the system will take the first `main_stat_count` stats as main stats. And then just enter `Agility,Intellect,Stamina,Crit,Weapon Damage` into the `stats` setting, and then set `main_stat_count` to 3. When these values are expected to be used as properties, the `ESS` singleton will create snake_cased versions automatically. `String stat_get_property_name(id: int) const` inside the ESS singleton for example. So in the example case `ESS.stat_get_property_name(4)` would return `weapon_damage`. ## ESSResourceDB This is a class that maps ids to resources for quick lookups. This is necessary in order to support networking, because you don't want to send resource paths over the network every time somebody casts a spell for example. ### ESSResourceDBStatic Simple static resource db. Just drag and drop all your data that you use into it with the inspector. Stores the data as vectors. Supports id remapping, which means that it can assign new ids to all added resources, so they don't clash. The added resource's index will be set as it's id. This is useful for modding support, as you can just collect every mod's resource dbs, and add them to a static db, and with this option enabled the ids will not clash. You can see an example of this [here](https://github.com/Relintai/broken_seals/blob/master/game/scripts/game_modules/DataManager.gd). ### ESSResourceDBMap Stores everything as a vector, and a map. #### ESSResourceDBFolders Inherited from `ESSResourceDBMap`. It will load everything from the folders that you set up into it's `folders` property. ## Entity This is the main class that can be used for players/mobs/npcs and also other things like chests. I ended up merging subclass functionality into it, because that way it gains a lot more utility, by sacrificing only a small amount of memory. For example this way it is easy to make chests attack the player, or make spell that animate objects. ## Entity Body Originally entities used to be inherited from `Spatial` or `Node2D`, so they could contain/drive their own models, but eventually on order to support both 2d, and 3d, bodies were separated from them. This unfortunately complicates the setup a bit, but the upsides overweight the downsides, as this way you don't need to create different entities for every model/body you have. Bodies are stored at `EntityData->EntitySpeciesData->ModelDatas (SpeciesModelData)->Body` When an `Entity` gets initialized, it will instance it's body automatically, but if you want to intance it yourself, you can call `void instance_body(entity_data: EntityData, model_index: int)` on an `Entity`. The `model_index` property tell the `Entity` which one it should use. Instancing bodies does not happen immediately, but you will probably want to set an `Entity`'s position right where you create it, a few helpers were added:\ `void set_transform_2d(transform: Transform2D, only_stored: bool = false)`\ `void set_transform_3d(transform: Transform, only_stored: bool = false)` Your body implementation then can get this from an entity an set itself to the right place. ### CharacterSkeletons CharacterSkeletons handle the looks of your characters. They come in two variants, one for 2d, one for 3d. They have quite a few helper methods. They can store ModelVisuals, and ModelVisualEntries. They support attach points. For example a character's hand. It adds properties based on the selected entity_type. These are based on the values from `ProjectSettings->ESS->Enums->skeletons_bone_attachment_points`. If you want to merge meshes this is where you can implement it. #### CharacterSkeleton3D The 3d variant. [Complex 3d skeleton scene](https://github.com/Relintai/broken_seals/blob/master/game/models/entities/human/models/armature_huf.tscn) \ [Complex 3d skeleton script](https://github.com/Relintai/broken_seals/blob/master/game/player/CharacterSkeletonGD.gd) #### CharacterSkeleton2D The 2d variant. [Simple 2d roguelike skeleton script](https://github.com/Relintai/broken_seals_roguelike/blob/master/game/characters/SimpleCharacter.gd) \ [Simple 2d roguelike skeleton scene](https://github.com/Relintai/broken_seals_roguelike/blob/master/game/characters/SimpleCharacter.tscn) #### ModelVisual A collection ModelVisualEntries. You will need to use this to define a look. For example if you have an item that will change your character's clothes, you will use this. ##### ModelVisualEntry Contains meshes, textures, texture tints, mesh transforms. It has 2 modes, `Bone` and `Attachment`. In the bone mode, you need to select an entity type, and then a concrete bone. This is the "merge this into the final character mesh" mode. In the attachment mode, you need to select a common attach point (`ProjectSettings->Ess->enums->skeletons_bone_attachment_points`), and the containing mesh will be put on to that point by the CharacterSkeleton. This is how you can implement weapons for example. ### EntitySpeciesData Contains data related to a species, like `SpeciesModelData`s, and species specific spells, and auras. #### SpeciesModelData Contains a scene of a species's body and it's customizations. The `customizable_slots_string` and `customizable_colors_string` should be filled with a comma separated string, they will add properties. Currently you need to click on something else, and back on the resource for these to show up, after a change to the strings. The body can be any scene, Entity will instance it, and set it to it's body property. The body should handle movement based on the player's input, it should handle sending position information through the network, if you want networking, it might (`CharacterSkeleton`s can also do it) also drive your animations/animation players if you have it. Bodies does not need to handle the graphics themselves (`ModelVisualEntries` for example) (you can implement your logic here if you want to), but the `CharacterSkeleton` classes exist for that purpose. [Complex 3d body script](https://github.com/Relintai/broken_seals/blob/master/game/player/Body.gd) \ [Complex 3d body scene](https://github.com/Relintai/broken_seals/blob/master/game/models/entities/human/models/HumanFemale.tscn) [Simple 2d roguelike body script](https://github.com/Relintai/broken_seals_roguelike/blob/master/game/player/Body.gd) \ [Simple 2d roguelike body scene](https://github.com/Relintai/broken_seals_roguelike/blob/master/game/player/Body.gd) #### SpeciesInstance This class will store character model customization data. E.g. which hairstyle you want for an `Entity`. Not yet finished! ### Spawning Since spawning (= creating) entities is entirely dependent on the type of game you are making, ESS cannot do everything for you. It will set up stats, equipment etc, but there is no way to set up positions for example. You can implement your spawning logic by inheriting from `ESSEntitySpawner`, and implementing `_request_entity_spawn`. You should only have one spawner at any given time. It will register itself into the ESS singleton automatically. Since it is inherited from Node, I recommend that you create an autoload for it. The ESS singleton also contains convenience methods to request spawning an Entity. [Sample 3d spawner implementation](https://github.com/Relintai/broken_seals/blob/master/game/player/bs_entity_spawner.gd) \ [Sample 2d spawner implementation](https://github.com/Relintai/broken_seals_roguelike/blob/master/game/player/bs_entity_spawner.gd) #### EntityCreateInfo Entity spawning usually requires a lot of complexity and hassle, this helper class aims to make it painless. All methods that deal with spawning will take this as a parameter. ### EntityData Since setting up Entities as scenes is usually quite the hassle, `EntityData` had to be created. It stores everything an entity needs. In order to spawn an entity you need it. #### EntityClassData `EntityClassData` holds class-related information, like specs (`CharacterSpec`), spells, start spells, start auras, alternative ais, `EntityResource`s (mana for example). #### CharacterSpec `CharacterSpec` holds spec-related information, most notably talents. #### EntityResource EntityResources are things like mana, health, or speed. These add greater flexibility over stats. The resource system is quite flexible, if you add a resource serverside, it will be automatically added clientside. (You have to add `EntityResource`s to the active `ESSResourceDB`!) By default all entities have the build in speed and health resources, as a set index (`EntityEnums::ENTITY_RESOURCE_INDEX_HEALTH` and `EntityEnums::ENTITY_RESOURCE_INDEX_SPEED`). There is also the `EntityEnums::ENTITY_RESOURCE_INDEX_RESOURCES_BEGIN` constant, so you have the current offset where the custom resources start. Entity allocates these in it's `_initialize()` virtual method, if you want to customize them. Note that `EntityClassData` contains an array, so you can add more resources easily to classes, these will be automatically added when the system initializes an `Entity`. ##### EntityResourceHealth The standard health resource implementation. ##### EntityResourceSpeed The standard speed resource implementation. #### EntityResourceCostData This is the class taht lets you implement resource costs. For example mana cost for a spell. ##### EntityResourceCostDataResource The standard resource cost implementation. ##### EntityResourceCostDataHealth The standard health resource cost implementation. It has a resource property, so you can just assign any resource to this. ### Interactions If you want your player to interact with it's target. For example a vendor, or loot. First make sure that you can interact, by checking `Entity.cans_interact()` or `Entity.canc_interact()`. If this returns true, you can call `Entity.crequest_interact()`. This will call `Entity.sinteract()` serverside. Interactions are handled by `EntityData` by default. It has the same methods. If `EntityData` is not set, the `Entity` will try to call the same overridable on itself. You can see an example implementation [here](https://github.com/Relintai/broken_seals/blob/master/game/scripts/entities/EntityDataGD.gd). ### AI You can implement ai by extending `EntityAI`, and then assigning it to an `EntityData`. When an `Entity` gets spawned it will create a copy for itself, so you can safely use class variables. #### AIFormation Not yet finished, it was meant as a way to calculate offset pet positions, (If an `Entity` has let's say 4 pets you don't just want them all to stay on top of their controller). If this functionality ends up in `EntityAI`, after pets are finished, this will be removed. ### Pets Unfortunately pet support is not yet finished. It is mostly done though, so you will see pet-related methods scattered around. ### Bags Stores items. See `Bag`. It has quite a few virtual methods, you should be able to implement most inventory types should you want to. Entity will send these over the network. Also Entities have a target bag property. For example this makes vendors easily implementable. ### VRPCs Entities has a networked visibility system. The method itself is called `vrpc`, it works the same way as normal rpcs. If you want to send data to every client that sees the current entity, use this. ## Spells, Auras, Talents Spell is the class you need to create both spells, and aura.\ It stores the data, and also it has the ability to be scripted.\ Talents are actually just spells used as Auras. Right now the system just applies them as a permanent aura.\ You don't need to worry about applying auras, cast them as spells instead. It they are set to permanent, or they have a duration set they will be applied as an aura automatically. Talent ranks are implemented by deapplying the earlier rank first, then applying the new rank. ### How to Request casting a spell clientside: `void spell_crequest_cast(spell_id: int)` \ Request to learn a spell clientside: `void spell_learn_requestc(id: int)` Request talent learning clientside: \ `void character_talent_crequest_learn(spec_index: int, character_talent_row: int, character_talent_culomn: int)` or \ `void class_talent_crequest_learn(spec_index: int, class_talent_row: int, class_talent_culomn: int)` #### Cast a spell Note that you should only do this serverside. ``` # Or get it from the active ESSResourceDB, etc export(Spell) var spell : Spell func scast_spell() -> void: var sci : SpellCastInfo = SpellCastInfo.new() sci.caster = info.caster sci.target = info.target sci.has_cast_time = spell.cast_enabled sci.cast_time = spell.cast_cast_time sci.spell_scale = info.spell_scale sci.set_spell(spell) spell.cast_starts(sci) ``` #### Apply an aura Normally you shouldn't do this, this is for more advanced uses. Cast the aura as a spell instead. Note that you should only apply auras serverside, they will be sent to clients automatically. ``` # Or get it from the active ESSResourceDB, etc export(Spell) var aura : Spell func sapply_aura() -> void: var ainfo : AuraApplyInfo = AuraApplyInfo.new() ainfo.caster = info.caster ainfo.target = info.caster ainfo.spell_scale = 1 ainfo.aura = aura aura.sapply(ainfo) ``` #### UI [Complete UI Implemetation](https://github.com/Relintai/broken_seals/tree/master/game/ui/player) [Player UI Core Implemetation](https://github.com/Relintai/broken_seals/tree/master/game/ui/player/player_ui) [Aura Frame Implementation](https://github.com/Relintai/broken_seals/tree/master/game/ui/player/auraframe) \ [Castbar Implementation](https://github.com/Relintai/broken_seals/tree/master/game/ui/player/castbar) \ [Unitframe Implementation](https://github.com/Relintai/broken_seals/tree/master/game/ui/player/unitframes) [Actionbar Implementation](https://github.com/Relintai/broken_seals/tree/master/game/ui/player/actionbars) [Character Window Implementation](https://github.com/Relintai/broken_seals/tree/master/game/ui/player/character) \ [Inventory Window Implementation](https://github.com/Relintai/broken_seals/tree/master/game/ui/player/bags) \ [Crafting Window Implementation](https://github.com/Relintai/broken_seals/tree/master/game/ui/player/crafting) \ [Loot Window Implementation](https://github.com/Relintai/broken_seals/tree/master/game/ui/player/loot_window) \ [Talent Window Implemetation](https://github.com/Relintai/broken_seals/tree/master/game/ui/player/talents) \ [Spellbook Window Implementation](https://github.com/Relintai/broken_seals/tree/master/game/ui/player/spellbook) \ [Vendor Window Implementation](https://github.com/Relintai/broken_seals/tree/master/game/ui/player/vendor_window) \ [Trainer Window Implementation](https://github.com/Relintai/broken_seals/tree/master/game/ui/player/trainer) [3D Nameplate Implementation](https://github.com/Relintai/broken_seals/tree/master/game/ui/world/nameplates) \ [2D Nameplate Implementation](https://github.com/Relintai/broken_seals_roguelike/tree/master/game/ui/nameplates) ### Infos / Pipelines #### SpellCastInfo Stores information about the state of a spell's cast. #### AuraApplyInfo Helps to apply auras #### SpellDamageInfo, SpellHealInfo These are used in the damage and heal calculation. For example these can be used to implement immunities, or absorb effects by modifying their damage values in aura callbacks. ### Projectiles Spells support projectiles, they are created/set up inside `void handle_projectile(info: SpellCastInfo)`. The default implementation will instance `Spell`'s projectile scene (if set), and then it will try to call a `void setup_projectile(info: SpellCastInfo)` on it if exists. You can override this behaviour by implementing your own `_void handle_projectile(info: SpellCastInfo)` on `Spell` Note that the module already adds `SpellFollowProjectile3D`, but this has not been finished yet. ## Items Items are implemented using 2 classes, `ItemTemplate`, and `ItemInstance`. `ItemTemplate` contains all information for a potential item. You can generate `Iteminstance`s with this, using it's `ItemInstance create_item_instance()` method. You can also implement your custom item creation logic using the `void _create_item_instance()` virtual. `ItemInstance` is the actual item. ### Loot Looting can be implemented using `Entity`'s target bag functionality. You can see an example implementation [here](https://github.com/Relintai/broken_seals/blob/master/game/scripts/entities/EntityDataGD.gd). \ And an example ui implementation [here](https://github.com/Relintai/broken_seals/tree/master/game/ui/player/loot_window). ## XP You can set all the xp values for your levels in `ProjectSettings->Ess->xp`. Now you can start distributing xp, for whatever you'd like to Entities, using `Entity.xp_adds(vlaue : int)` ## Examples Eventually I'll create a separate repository with a few examples/demos, but for now you can check the game I've been working on for examples. 3d: https://github.com/Relintai/broken_seals.git 2d turn based: https://github.com/Relintai/broken_seals_roguelike 2d: https://github.com/Relintai/broken_seals_2d.git ## Compiling First make sure that you can compile godot. See the official docs: https://docs.godotengine.org/en/3.x/development/compiling/index.html 1. Clone the engine if you haven't already: If you want Godot 3.x: ```git clone -b 3.x https://github.com/godotengine/godot.git godot``` If you want Godot 4.0: ```git clone https://github.com/godotengine/godot.git godot``` 2. go into the modules folder inside the engine's directory" ```cd godot``` ```cd modules``` 3. clone this repository ```git clone https://github.com/Relintai/entity_spell_system.git entity_spell_system``` (the folder needs to be named entity_spell_system!) 4. Go up one folder ```cd ..``` 5. Compile godot. For example: ```scons p=x11 t=release_debug tools=yes``` ================================================ FILE: SCsub ================================================ import os Import('env') module_env = env.Clone() if os.path.isdir('../mesh_data_resource'): module_env.Append(CPPDEFINES=['MESH_DATA_RESOURCE_PRESENT']) if os.path.isdir('../props'): module_env.Append(CPPDEFINES=['PROPS_PRESENT']) has_texture_packer = False if os.path.isdir('../texture_packer'): has_texture_packer = True module_env.Append(CPPDEFINES=['TEXTURE_PACKER_PRESENT']) sources = [ "register_types.cpp", "entity_enums.cpp", "spell_enums.cpp", "item_enums.cpp", "data/auras/aura_group.cpp", "data/items/item_instance.cpp", "data/items/item_template.cpp", "data/items/equipment_data.cpp", "data/items/craft_recipe_helper.cpp", "data/items/craft_recipe.cpp", "data/items/model_visual.cpp", "data/items/model_visual_entry.cpp", "data/species/entity_species_data.cpp", "data/species/species_model_data.cpp", "data/species/species_instance.cpp", "data/spells/spell_cooldown_manipulation_data.cpp", "data/spells/spell.cpp", "data/spells/spell_effect_visual.cpp", "data/spells/spell_effect_visual_simple.cpp", "data/atlases/character_atlas.cpp", "data/atlases/character_atlas_entry.cpp", "entities/data/entity_data.cpp", "entities/data/entity_class_data.cpp", "entities/data/vendor_item_data.cpp", "entities/data/vendor_item_data_entry.cpp", "entities/data/entity_data_container.cpp", "entities/data/item_container_data.cpp", "entities/data/item_container_data_entry.cpp", "entities/skills/entity_skill.cpp", "entities/skills/entity_skill_data.cpp", "entities/data/character_spec.cpp", "skeleton/character_bones.cpp", "entities/stats/stat_data.cpp", "entities/stats/level_stat_data.cpp", "entities/stats/simple_level_stat_data.cpp", "entities/stats/complex_level_stat_data.cpp", "inventory/bag.cpp", #"inventory/inventory.cpp", "infos/aura_infos.cpp", "infos/spell_cast_info.cpp", "pipelines/spell_damage_info.cpp", "pipelines/spell_heal_info.cpp", "entities/auras/aura_data.cpp", "entities/entity.cpp", "entities/resources/entity_resource_cost_data.cpp", "entities/resources/entity_resource_cost_data_health.cpp", "entities/resources/entity_resource_cost_data_resource.cpp", "entities/resources/entity_resource.cpp", "entities/resources/entity_resource_health.cpp", "entities/resources/entity_resource_speed.cpp", "drag_and_drop/es_drag_and_drop.cpp", "skeleton/character_skeleton_2d.cpp", "skeleton/character_skeleton_3d.cpp", "skeleton/skeleton_model_entry.cpp", "utility/entity_create_info.cpp", "data/loot/loot_data_base.cpp", "entities/ai/entity_ai.cpp", "formations/ai_formation.cpp", "projectiles/3d/spell_follow_projectile_3d.cpp", "profiles/input/input_profile_modifier.cpp", "profiles/input/input_profile_modifier_entry.cpp", "profiles/input/input_profile.cpp", "profiles/actionbar/action_bar_button_entry.cpp", "profiles/actionbar/action_bar_entry.cpp", "profiles/actionbar/action_bar_profile.cpp", "profiles/class_profile.cpp", "profiles/player_profile.cpp", "spawners/ess_entity_spawner.cpp", "singletons/profile_manager.cpp", "singletons/ess.cpp", "database/ess_resource_db.cpp", "database/ess_resource_db_static.cpp", "database/ess_resource_db_map.cpp", "database/ess_resource_db_folders.cpp", "editor/ess_editor_plugin.cpp", "props/prop_data_entity.cpp", "material_cache/ess_material_cache.cpp" ] if has_texture_packer: sources.append("material_cache/ess_material_cache_pcm.cpp") if ARGUMENTS.get('custom_modules_shared', 'no') == 'yes': # Shared lib compilation module_env.Append(CCFLAGS=['-fPIC']) module_env['LIBS'] = [] shared_lib = module_env.SharedLibrary(target='#bin/ess', source=sources) shared_lib_shim = shared_lib[0].name.rsplit('.', 1)[0] env.Append(LIBS=[shared_lib_shim]) env.Append(LIBPATH=['#bin']) else: # Static compilation module_env.add_source_files(env.modules_sources, sources) ================================================ FILE: config.py ================================================ def can_build(env, platform): return True def configure(env): pass def get_doc_classes(): return [ "CharacterAtlasEntry", "CharacterAtlas", "ESS", "AuraGroup", "CraftRecipeHelper", "CraftRecipe", "EquipmentData", "ItemInstance", "ItemTemplate", "ModelVisualEntry", "ModelVisual", "SpellCooldownManipulationData", "SpellEffectVisualSimple", "SpellEffectVisual", "Spell", "ESDragAndDrop", "EntityAI", "AuraData", "CharacterSpec", "EntityClassData", "EntityDataContainer", "EntityData", "ItemContainerDataEntry", "ItemContainerData", "VendorItemDataEntry", "VendorItemData", "EntityResourceCostData", "EntityResourceCostDataHealth", "EntityResourceCostDataResource", "EntityResource", "EntityResourceHealth", "EntityResourceSpeed", "EntitySkillData", "EntitySkill", "ComplexLevelStatData", "LevelStatData", "SimpleLevelStatData", "StatData", "StatModifier", "Entity", "AIFormation", "AuraApplyInfo", "SpellCastInfo", "Bag", "LootDataBase", "SpellDamageInfo", "SpellHealInfo", "ActionBarButtonEntry", "ActionBarEntry", "ActionBarProfile", "InputProfileModifierEntry", "InputProfileModifier", "InputProfile", "ClassProfile", "PlayerProfile", "ProfileManager", "CharacterBones", "CharacterSkeleton3D", "CharacterSkeleton2D", "CharacterSkeleton", "EntitySpeciesData", "SpeciesInstance", "SkeletonModelEntry", "SpeciesModelData", "EntityCreateInfo", "SpellFollowProjectile3D", "ESSResourceDB", "ESSResourceDBFolders", "ESSResourceDBStatic", "ESSResourceDBMap", "EntityEnums", "ItemEnums", "SpellEnums", "ESSEntitySpawner", "PropDataEntity", "ESSMaterialCache", "ESSMaterialCachePCM", ] def get_doc_path(): return "doc_classes" ================================================ FILE: data/atlases/character_atlas.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "character_atlas.h" CharacterAtlas::CharacterAtlas() { } void CharacterAtlas::_bind_methods() { } ================================================ FILE: data/atlases/character_atlas.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef CHARACTER_ATLAS_H #define CHARACTER_ATLAS_H #include "core/version.h" #include "core/io/resource.h" class CharacterAtlas : public Resource { GDCLASS(CharacterAtlas, Resource); public: CharacterAtlas(); protected: static void _bind_methods(); //private: }; #endif ================================================ FILE: data/atlases/character_atlas_entry.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "character_atlas_entry.h" CharacterAtlasEntry::CharacterAtlasEntry() { } void CharacterAtlasEntry::_bind_methods() { } ================================================ FILE: data/atlases/character_atlas_entry.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef CHARACTER_ATLAS_ENTRY_H #define CHARACTER_ATLAS_ENTRY_H #include "core/version.h" #include "core/io/resource.h" class CharacterAtlasEntry : public Resource { GDCLASS(CharacterAtlasEntry, Resource); public: CharacterAtlasEntry(); protected: static void _bind_methods(); //private: }; #endif ================================================ FILE: data/auras/aura_group.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "aura_group.h" AuraGroup::AuraGroup() { } void AuraGroup::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "text_description"), "set_name", "get_name"); } ================================================ FILE: data/auras/aura_group.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef AURA_GROUP_H #define AURA_GROUP_H #include "core/version.h" #include "core/io/resource.h" class AuraGroup : public Resource { GDCLASS(AuraGroup, Resource); public: AuraGroup(); protected: static void _bind_methods(); }; #endif ================================================ FILE: data/items/craft_recipe.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "craft_recipe.h" const String CraftRecipe::BINDING_STRING_CRAFT_CATEGORIES = "None,Alchemy,Smithing,Tailoring,Enchanting,Engineering"; const String CraftRecipe::BINDING_STRING_CRAFT_SUB_CATEGORIES = "None,Potions"; int CraftRecipe::get_id() const { return _id; } void CraftRecipe::set_id(const int value) { _id = value; } CraftRecipe::CraftCategories CraftRecipe::get_category() const { return _category; } void CraftRecipe::set_category(const CraftCategories value) { _category = value; } CraftRecipe::CraftSubCategories CraftRecipe::get_sub_category() const { return _sub_category; } void CraftRecipe::set_sub_category(const CraftSubCategories value) { _sub_category = value; } Ref CraftRecipe::get_required_tool(const int index) { return _required_tools[index]; } void CraftRecipe::set_required_tool(const int index, const Ref &value) { _required_tools[index] = value; } int CraftRecipe::get_required_tools_count() const { return _required_tools_count; } void CraftRecipe::set_required_tools_count(const int value) { _required_tools_count = value; } void CraftRecipe::set_required_material(const int index, const Ref &value) { _required_materials[index] = value; } Ref CraftRecipe::get_required_material(int index) { return _required_materials[index]; } int CraftRecipe::get_required_materials_count() const { return _required_materials_count; } void CraftRecipe::set_required_materials_count(const int value) { _required_materials_count = value; } Ref CraftRecipe::get_item() { return _item; } void CraftRecipe::set_item(const Ref &value) { _item = value; } CraftRecipe::CraftRecipe() { _id = 0; _category = CraftCategories::CRAFT_CATEGORY_NONE; _sub_category = CraftSubCategories::CRAFT_SUB_CATEGORY_NONE; //_item = Ref(memnew(CraftRecipeHelper())); _required_materials_count = 0; _required_tools_count = 0; //for (int i = 0; i < MAX_REQUIRED_TOOLS; ++i) { // _required_tools[i] = Ref(memnew(CraftRecipeHelper())); //} //for (int i = 0; i < MAX_REQUIRED_MATERIALS; ++i) { // _required_materials[i] = Ref(memnew(CraftRecipeHelper())); //} } CraftRecipe::~CraftRecipe() { //TODO check if the array destrutors actually unref the objects. //_item = Ref(NULL); } void CraftRecipe::_validate_property(PropertyInfo &property) const { String prop = property.name; if (prop.begins_with("RequiredMaterials_")) { int frame = prop.get_slicec('/', 0).get_slicec('_', 1).to_int(); if (frame >= _required_materials_count) { property.usage = 0; } } else if (prop.begins_with("RequiredTools_")) { int frame = prop.get_slicec('/', 0).get_slicec('_', 1).to_int(); if (frame >= _required_tools_count) { property.usage = 0; } } } void CraftRecipe::_bind_methods() { ClassDB::bind_method(D_METHOD("get_id"), &CraftRecipe::get_id); ClassDB::bind_method(D_METHOD("set_id", "value"), &CraftRecipe::set_id); ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text_name"), "set_name", "get_name"); ClassDB::bind_method(D_METHOD("get_category"), &CraftRecipe::get_category); ClassDB::bind_method(D_METHOD("set_category", "value"), &CraftRecipe::set_category); ADD_PROPERTY(PropertyInfo(Variant::INT, "category", PROPERTY_HINT_ENUM, CraftRecipe::BINDING_STRING_CRAFT_CATEGORIES), "set_category", "get_category"); ClassDB::bind_method(D_METHOD("get_sub_category"), &CraftRecipe::get_sub_category); ClassDB::bind_method(D_METHOD("set_sub_category", "value"), &CraftRecipe::set_sub_category); ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_category", PROPERTY_HINT_ENUM, CraftRecipe::BINDING_STRING_CRAFT_SUB_CATEGORIES), "set_sub_category", "get_sub_category"); ClassDB::bind_method(D_METHOD("get_required_material"), &CraftRecipe::get_required_material); ClassDB::bind_method(D_METHOD("set_required_material", "mat"), &CraftRecipe::set_required_material); ClassDB::bind_method(D_METHOD("get_required_materials_count"), &CraftRecipe::get_required_materials_count); ClassDB::bind_method(D_METHOD("set_required_materials_count", "count"), &CraftRecipe::set_required_materials_count); ADD_PROPERTY(PropertyInfo(Variant::INT, "required_materials_count", PROPERTY_HINT_RANGE, "0," + itos(MAX_REQUIRED_MATERIALS), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_required_materials_count", "get_required_materials_count"); for (int i = 0; i < MAX_REQUIRED_MATERIALS; i++) { ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "RequiredMaterials_" + itos(i) + "", PROPERTY_HINT_RESOURCE_TYPE, "CraftRecipeHelper", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_required_material", "get_required_material", i); } ClassDB::bind_method(D_METHOD("get_required_tool"), &CraftRecipe::get_required_tool); ClassDB::bind_method(D_METHOD("set_required_tool", "value"), &CraftRecipe::set_required_tool); ClassDB::bind_method(D_METHOD("get_required_tools_count"), &CraftRecipe::get_required_tools_count); ClassDB::bind_method(D_METHOD("set_required_tools_count", "value"), &CraftRecipe::set_required_tools_count); ADD_PROPERTY(PropertyInfo(Variant::INT, "required_tools_count", PROPERTY_HINT_RANGE, "0," + itos(MAX_REQUIRED_TOOLS), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_required_tools_count", "get_required_tools_count"); for (int i = 0; i < MAX_REQUIRED_TOOLS; i++) { ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "RequiredTools_" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "CraftRecipeHelper", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_required_tool", "get_required_tool", i); } ClassDB::bind_method(D_METHOD("get_item"), &CraftRecipe::get_item); ClassDB::bind_method(D_METHOD("set_item", "value"), &CraftRecipe::set_item); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "CraftRecipeHelper"), "set_item", "get_item"); BIND_CONSTANT(MAX_REQUIRED_TOOLS); BIND_CONSTANT(MAX_REQUIRED_MATERIALS); BIND_ENUM_CONSTANT(CRAFT_CATEGORY_NONE); BIND_ENUM_CONSTANT(CRAFT_CATEGORY_ALCHEMY); BIND_ENUM_CONSTANT(CRAFT_CATEGORY_SMITHING); BIND_ENUM_CONSTANT(CRAFT_CATEGORY_TAILORING); BIND_ENUM_CONSTANT(CRAFT_CATEGORY_ENCHANTING); BIND_ENUM_CONSTANT(CRAFT_CATEGORY_ENGINEERING); BIND_ENUM_CONSTANT(CRAFT_SUB_CATEGORY_NONE); BIND_ENUM_CONSTANT(CRAFT_SUB_CATEGORY_POTIONS); } ================================================ FILE: data/items/craft_recipe.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef CRAFT_RECIPE_H #define CRAFT_RECIPE_H #include "core/version.h" #include "core/io/resource.h" #include "core/templates/vector.h" #include "core/string/ustring.h" #include "item_template.h" #include "craft_recipe_helper.h" class CraftRecipe : public Resource { GDCLASS(CraftRecipe, Resource); public: static const String BINDING_STRING_CRAFT_CATEGORIES; static const String BINDING_STRING_CRAFT_SUB_CATEGORIES; enum CraftCategories { CRAFT_CATEGORY_NONE, CRAFT_CATEGORY_ALCHEMY, CRAFT_CATEGORY_SMITHING, CRAFT_CATEGORY_TAILORING, CRAFT_CATEGORY_ENCHANTING, CRAFT_CATEGORY_ENGINEERING, }; enum CraftSubCategories { CRAFT_SUB_CATEGORY_NONE, CRAFT_SUB_CATEGORY_POTIONS, }; public: int get_id() const; void set_id(const int value); CraftCategories get_category() const; void set_category(const CraftCategories value); CraftSubCategories get_sub_category() const; void set_sub_category(const CraftSubCategories value); //Tools Ref get_required_tool(int index); void set_required_tool(const int index, const Ref &value); int get_required_tools_count() const; void set_required_tools_count(const int value); //Materials Ref get_required_material(const int index); void set_required_material(const int index, const Ref &value); int get_required_materials_count() const; void set_required_materials_count(const int value); //Item Ref get_item(); void set_item(const Ref &value); CraftRecipe(); ~CraftRecipe(); protected: static void _bind_methods(); void _validate_property(PropertyInfo &property) const; private: enum { MAX_REQUIRED_MATERIALS = 6, //Increase if necessary, should be enough for now MAX_REQUIRED_TOOLS = 6 //Increase if necessary, should be enough for now }; int _id; String _text_name; CraftCategories _category; CraftSubCategories _sub_category; int _required_tools_count; Ref _required_tools[MAX_REQUIRED_TOOLS]; int _required_materials_count; Ref _required_materials[MAX_REQUIRED_MATERIALS]; Ref _item; }; VARIANT_ENUM_CAST(CraftRecipe::CraftSubCategories); VARIANT_ENUM_CAST(CraftRecipe::CraftCategories); #endif ================================================ FILE: data/items/craft_recipe_helper.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "craft_recipe_helper.h" Ref CraftRecipeHelper::get_item() { return _item; } void CraftRecipeHelper::set_item(Ref value) { _item = value; } int CraftRecipeHelper::get_count() { return _count; } void CraftRecipeHelper::set_count(int value) { _count = value; } CraftRecipeHelper::CraftRecipeHelper(Ref item, int count) { set_item(item); set_count(count); } CraftRecipeHelper::CraftRecipeHelper() { set_count(0); } CraftRecipeHelper::~CraftRecipeHelper() { } void CraftRecipeHelper::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item"), &CraftRecipeHelper::get_item); ClassDB::bind_method(D_METHOD("set_item", "value"), &CraftRecipeHelper::set_item); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "ItemTemplate"), "set_item", "get_item"); ClassDB::bind_method(D_METHOD("get_count"), &CraftRecipeHelper::get_count); ClassDB::bind_method(D_METHOD("set_count", "value"), &CraftRecipeHelper::set_count); ADD_PROPERTY(PropertyInfo(Variant::INT, "count"), "set_count", "get_count"); } ================================================ FILE: data/items/craft_recipe_helper.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef CRAFT_RECIPE_HELPER_H #define CRAFT_RECIPE_HELPER_H #include "core/version.h" #include "core/io/resource.h" #include "item_template.h" class CraftRecipeHelper : public Resource { GDCLASS(CraftRecipeHelper, Resource); public: Ref get_item(); void set_item(Ref value); int get_count(); void set_count(int value); CraftRecipeHelper(Ref item, int count); CraftRecipeHelper(); ~CraftRecipeHelper(); protected: static void _bind_methods(); private: Ref _item; int _count; }; #endif ================================================ FILE: data/items/equipment_data.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "equipment_data.h" #include "item_instance.h" #include "item_template.h" #include "../../singletons/ess.h" Ref EquipmentData::get_slot(int index) { ERR_FAIL_INDEX_V(index, ESS::get_singleton()->equip_slot_get_count(), Ref()); return _entries[index]; } void EquipmentData::set_slot(int index, Ref entry) { ERR_FAIL_INDEX(index, ESS::get_singleton()->equip_slot_get_count()); _entries.write[index] = entry; } Ref EquipmentData::get_item(int index) { ERR_FAIL_INDEX_V(index, ESS::get_singleton()->equip_slot_get_count(), Ref()); Ref ede = _entries[index]; if (!ede.is_valid()) return Ref(); return ede->create_item_instance(); } EquipmentData::EquipmentData() { _entries.resize(ESS::get_singleton()->equip_slot_get_count()); } EquipmentData::~EquipmentData() { _entries.clear(); } bool EquipmentData::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; if (name.get_slicec('/', 0) == "slot") { StringName prop = name.get_slicec('/', 1); if (ESS::get_singleton()->equip_slot_is_property(prop)) { int id = ESS::get_singleton()->equip_slot_get_property_id(prop); if (_entries.size() < id) { return false; } _entries.set(id, p_value); return true; } else { return false; } } else { return false; } return true; } bool EquipmentData::_get(const StringName &p_name, Variant &r_ret) const { String name = p_name; if (name.get_slicec('/', 0) == "slot") { StringName prop = name.get_slicec('/', 1); if (ESS::get_singleton()->equip_slot_is_property(prop)) { int id = ESS::get_singleton()->equip_slot_get_property_id(prop); if (_entries.size() < id) { return false; } r_ret = _entries[id]; return true; } else { return false; } } else { return false; } return true; } void EquipmentData::_get_property_list(List *p_list) const { for (int i = 0; i < ESS::get_singleton()->equip_slot_get_count(); ++i) { p_list->push_back(PropertyInfo(Variant::OBJECT, "slot/" + ESS::get_singleton()->equip_slot_get_property_name(i), PROPERTY_HINT_RESOURCE_TYPE, "ItemTemplate")); } } void EquipmentData::_bind_methods() { ClassDB::bind_method(D_METHOD("get_slot", "index"), &EquipmentData::get_slot); ClassDB::bind_method(D_METHOD("set_slot", "index", "entry"), &EquipmentData::set_slot); } ================================================ FILE: data/items/equipment_data.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef EQUIPMENT_DATA_H #define EQUIPMENT_DATA_H #include "core/version.h" #include "core/io/resource.h" class ItemInstance; class ItemTemplate; class EquipmentData : public Resource { GDCLASS(EquipmentData, Resource); public: Ref get_slot(int index); void set_slot(int index, Ref entry); Ref get_item(int index); EquipmentData(); ~EquipmentData(); protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List *p_list) const; static void _bind_methods(); private: Vector > _entries; }; #endif ================================================ FILE: data/items/item_instance.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "item_instance.h" #include "item_template.h" #include "../../database/ess_resource_db.h" #include "../../singletons/ess.h" #include "core/version.h" Ref ItemInstance::get_item_template() { return _item_template; } void ItemInstance::set_item_template(const Ref &value) { _item_template = value; _item_template_path = ""; if (value.is_valid()) _item_template_path = value->get_path(); } int ItemInstance::stat_modifier_get_stat_id(const int index) const { ERR_FAIL_INDEX_V(index, _modifiers.size(), 0); return _modifiers[index].stat_id; } void ItemInstance::stat_modifier_set_stat_id(const int index, const int value) { ERR_FAIL_INDEX(index, _modifiers.size()); _modifiers.write[index].stat_id = value; } float ItemInstance::stat_modifier_get_base_mod(const int index) const { ERR_FAIL_INDEX_V(index, _modifiers.size(), 0); return _modifiers[index].base_mod; } void ItemInstance::stat_modifier_set_base_mod(const int index, const float value) { ERR_FAIL_INDEX(index, _modifiers.size()); _modifiers.write[index].base_mod = value; } float ItemInstance::stat_modifier_get_bonus_mod(const int index) const { ERR_FAIL_INDEX_V(index, _modifiers.size(), 0); return _modifiers[index].bonus_mod; } void ItemInstance::stat_modifier_set_bonus_mod(const int index, const float value) { ERR_FAIL_INDEX(index, _modifiers.size()); _modifiers.write[index].bonus_mod = value; } float ItemInstance::stat_modifier_get_percent_mod(const int index) const { ERR_FAIL_INDEX_V(index, _modifiers.size(), 0); return _modifiers[index].percent_mod; } void ItemInstance::stat_modifier_set_percent_mod(const int index, const float value) { ERR_FAIL_INDEX(index, _modifiers.size()); _modifiers.write[index].percent_mod = value; } void ItemInstance::add_item_stat_modifier(const int stat_id, const int base_mod, const int bonus_mod, const int percent_mod) { ItemStatModifier mod; mod.stat_id = stat_id; mod.base_mod = base_mod; mod.bonus_mod = bonus_mod; mod.percent_mod = percent_mod; _modifiers.push_back(mod); } void ItemInstance::remove_item_stat_modifier(const int index) { ERR_FAIL_INDEX(index, _modifiers.size()); _modifiers.remove_at(index); } void ItemInstance::clear_item_stat_modifiers() { _modifiers.clear(); } int ItemInstance::stat_modifier_get_count() const { return _modifiers.size(); } Vector ItemInstance::stat_modifiers_get() { Vector arr; arr.resize(_modifiers.size() * 4); for (int i = 0; i < _modifiers.size(); ++i) { int indx = i * 4; const ItemStatModifier &m = _modifiers[i]; arr.write[indx] = m.stat_id; arr.write[indx + 1] = m.base_mod; arr.write[indx + 2] = m.bonus_mod; arr.write[indx + 3] = m.percent_mod; } return arr; } void ItemInstance::stat_modifiers_set(const Vector &mods) { ERR_FAIL_COND((mods.size() % 4) != 0); _modifiers.resize(mods.size() / 4); for (int i = 0; i < _modifiers.size(); ++i) { int indx = i * 4; ItemStatModifier &m = _modifiers.write[i]; m.stat_id = mods[indx]; m.base_mod = mods[indx + 1]; m.bonus_mod = mods[indx + 2]; m.percent_mod = mods[indx + 3]; } } int ItemInstance::get_stack_size() const { return _stack_size; } void ItemInstance::set_stack_size(const int value) { _stack_size = value; emit_signal("stack_size_changed", Ref(this)); } int ItemInstance::get_charges() const { return _charges; } void ItemInstance::set_charges(const int value) { _charges = value; emit_signal("stack_charges_changed", Ref(this)); } String ItemInstance::get_description() { if (!has_method("_get_description")) return ""; return call("_get_description"); } Dictionary ItemInstance::to_dict() { return call("_to_dict"); } void ItemInstance::from_dict(const Dictionary &dict) { call("_from_dict", dict); } Dictionary ItemInstance::_to_dict() { Dictionary dict; dict["item_path"] = _item_template->get_path(); dict["stack_size"] = _stack_size; Array mods; for (int i = 0; i < _modifiers.size(); ++i) { Dictionary mdict; mdict["stat_id"] = _modifiers[i].stat_id; mdict["base_mod"] = _modifiers[i].base_mod; mdict["bonus_mod"] = _modifiers[i].bonus_mod; mdict["percent_mod"] = _modifiers[i].percent_mod; mods.append(mdict); } dict["modifiers"] = mods; return dict; } void ItemInstance::_from_dict(const Dictionary &dict) { ERR_FAIL_COND(dict.is_empty()); _item_template_path = dict.get("item_path", 0); if (ESS::get_singleton() != NULL) { _item_template = ESS::get_singleton()->get_resource_db()->get_item_template_path(_item_template_path); } _stack_size = dict.get("stack_size", 0); Array mods = dict.get("modifiers", Array()); for (int i = 0; i < mods.size(); ++i) { ItemStatModifier mod; Dictionary mdict = mods.get(i); mod.stat_id = dict.get("stat_id", 0); mod.base_mod = dict.get("base_mod", 0); mod.bonus_mod = dict.get("bonus_mod", 0); mod.percent_mod = dict.get("percent_mod", 0); _modifiers.push_back(mod); } } ItemInstance::ItemInstance() { _stack_size = 1; _charges = -1; } ItemInstance::~ItemInstance() { _modifiers.clear(); } void ItemInstance::_bind_methods() { ADD_SIGNAL(MethodInfo("stack_size_changed", PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "ItemInstance"))); ADD_SIGNAL(MethodInfo("stack_charges_changed", PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "ItemInstance"))); ClassDB::bind_method(D_METHOD("get_item_template"), &ItemInstance::get_item_template); ClassDB::bind_method(D_METHOD("set_item_template", "value"), &ItemInstance::set_item_template); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "item_template", PROPERTY_HINT_RESOURCE_TYPE, "ItemTemplate"), "set_item_template", "get_item_template"); ClassDB::bind_method(D_METHOD("get_stack_size"), &ItemInstance::get_stack_size); ClassDB::bind_method(D_METHOD("set_stack_size", "count"), &ItemInstance::set_stack_size); ADD_PROPERTY(PropertyInfo(Variant::INT, "stack_size"), "set_stack_size", "get_stack_size"); ClassDB::bind_method(D_METHOD("get_charges"), &ItemInstance::get_charges); ClassDB::bind_method(D_METHOD("set_charges", "size"), &ItemInstance::set_charges); ADD_PROPERTY(PropertyInfo(Variant::INT, "charges"), "set_charges", "get_charges"); ClassDB::bind_method(D_METHOD("stat_modifier_get_stat_id", "index"), &ItemInstance::stat_modifier_get_stat_id); ClassDB::bind_method(D_METHOD("stat_modifier_set_stat_id", "index", "value"), &ItemInstance::stat_modifier_set_stat_id); ClassDB::bind_method(D_METHOD("stat_modifier_get_base_mod", "index"), &ItemInstance::stat_modifier_get_base_mod); ClassDB::bind_method(D_METHOD("stat_modifier_set_base_mod", "index", "value"), &ItemInstance::stat_modifier_set_base_mod); ClassDB::bind_method(D_METHOD("stat_modifier_get_bonus_mod", "index"), &ItemInstance::stat_modifier_get_bonus_mod); ClassDB::bind_method(D_METHOD("stat_modifier_set_bonus_mod", "index", "value"), &ItemInstance::stat_modifier_set_bonus_mod); ClassDB::bind_method(D_METHOD("stat_modifier_get_percent_mod", "index"), &ItemInstance::stat_modifier_get_percent_mod); ClassDB::bind_method(D_METHOD("stat_modifier_set_percent_mod", "index", "value"), &ItemInstance::stat_modifier_set_percent_mod); ClassDB::bind_method(D_METHOD("add_item_stat_modifier", "stat_id", "base_mod", "bonus_mod", "percent_mod"), &ItemInstance::add_item_stat_modifier); ClassDB::bind_method(D_METHOD("remove_item_stat_modifier", "index"), &ItemInstance::remove_item_stat_modifier); ClassDB::bind_method(D_METHOD("clear_item_stat_modifiers"), &ItemInstance::clear_item_stat_modifiers); ClassDB::bind_method(D_METHOD("stat_modifier_get_count"), &ItemInstance::stat_modifier_get_count); ClassDB::bind_method(D_METHOD("stat_modifiers_get"), &ItemInstance::stat_modifiers_get); ClassDB::bind_method(D_METHOD("stat_modifiers_set", "mods"), &ItemInstance::stat_modifiers_set); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "stat_modifiers", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT, ""), "stat_modifiers_set", "stat_modifiers_get"); ////GDVIRTUAL_BIND("_get_description", "desc"); ClassDB::bind_method(D_METHOD("get_description"), &ItemInstance::get_description); //Serialization ////GDVIRTUAL_BIND("_from_dict", "dict"); ////GDVIRTUAL_BIND("_to_dict", "dict"); ClassDB::bind_method(D_METHOD("from_dict", "dict"), &ItemInstance::from_dict); ClassDB::bind_method(D_METHOD("to_dict"), &ItemInstance::to_dict); ClassDB::bind_method(D_METHOD("_from_dict", "dict"), &ItemInstance::_from_dict); ClassDB::bind_method(D_METHOD("_to_dict"), &ItemInstance::_to_dict); } ================================================ FILE: data/items/item_instance.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef ITEM_INSTANCE_H #define ITEM_INSTANCE_H #include "core/version.h" #include "core/io/resource.h" #include "core/templates/vector.h" #include "../../item_enums.h" class ItemTemplate; class ItemInstance : public Resource { GDCLASS(ItemInstance, Resource); public: Ref get_item_template(); void set_item_template(const Ref &value); //Modifiers int stat_modifier_get_stat_id(const int index) const; void stat_modifier_set_stat_id(const int index, const int value); float stat_modifier_get_base_mod(const int index) const; void stat_modifier_set_base_mod(const int index, const float value); float stat_modifier_get_bonus_mod(const int index) const; void stat_modifier_set_bonus_mod(const int index, const float value); float stat_modifier_get_percent_mod(const int index) const; void stat_modifier_set_percent_mod(const int index, const float value); void add_item_stat_modifier(const int stat_id, const int base_mod, const int bonus_mod, const int percent_mod); void remove_item_stat_modifier(const int index); void clear_item_stat_modifiers(); int stat_modifier_get_count() const; Vector stat_modifiers_get(); void stat_modifiers_set(const Vector &mods); int get_stack_size() const; void set_stack_size(const int value); int get_charges() const; void set_charges(const int value); String get_description(); Dictionary to_dict(); void from_dict(const Dictionary &dict); virtual Dictionary _to_dict(); virtual void _from_dict(const Dictionary &dict); ItemInstance(); ~ItemInstance(); protected: static void _bind_methods(); protected: struct ItemStatModifier { int stat_id; float base_mod; float bonus_mod; float percent_mod; ItemStatModifier() { stat_id = 0; base_mod = 0; bonus_mod = 0; percent_mod = 0; } }; private: Ref _item_template; StringName _item_template_path; int _stack_size; int _charges; Vector _modifiers; }; #endif ================================================ FILE: data/items/item_template.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "item_template.h" #include "../../entities/data/entity_class_data.h" #include "../spells/spell.h" #include "item_instance.h" #include "../../singletons/ess.h" #include "../../defines.h" int ItemTemplate::get_id() const { return _id; } void ItemTemplate::set_id(const int value) { _id = value; } ItemEnums::ItemType ItemTemplate::get_item_type() const { return _item_type; } void ItemTemplate::set_item_type(const ItemEnums::ItemType value) { _item_type = value; } ItemEnums::ItemSubtype ItemTemplate::get_item_sub_type() const { return _item_sub_type; } void ItemTemplate::set_item_sub_type(const ItemEnums::ItemSubtype value) { _item_sub_type = value; } ItemEnums::ItemSubSubtype ItemTemplate::get_item_sub_sub_type() const { return _item_sub_sub_type; } void ItemTemplate::set_item_sub_sub_type(const ItemEnums::ItemSubSubtype value) { _item_sub_sub_type = value; } ItemEnums::ItemRarity ItemTemplate::get_rarity() const { return _rarity; } void ItemTemplate::set_rarity(const ItemEnums::ItemRarity value) { _rarity = value; } ItemEnums::ArmorType ItemTemplate::get_armor_type() const { return _armor_type; } void ItemTemplate::set_armor_type(const ItemEnums::ArmorType value) { _armor_type = value; } int ItemTemplate::get_equip_slot() const { return _equip_slot; } void ItemTemplate::set_equip_slot(const int value) { _equip_slot = value; } Ref ItemTemplate::get_model_visual() const { return _model_visual; } void ItemTemplate::set_model_visual(const Ref &value) { _model_visual = value; } Ref ItemTemplate::get_required_character_class() const { return _required_character_class; } void ItemTemplate::set_required_character_class(const Ref &value) { _required_character_class = value; } int ItemTemplate::get_price() const { return _price; } void ItemTemplate::set_price(const int value) { _price = value; } int ItemTemplate::get_stack_size() const { return _stack_size; } void ItemTemplate::set_stack_size(const int value) { _stack_size = value; } Ref ItemTemplate::get_icon() const { return _icon; } void ItemTemplate::set_icon(const Ref &value) { _icon = value; } float ItemTemplate::get_scale_x() const { return _scale_x; } void ItemTemplate::set_scale_x(const float value) { _scale_x = value; } float ItemTemplate::get_scale_y() const { return _scale_y; } void ItemTemplate::set_scale_y(const float value) { _scale_y = value; } float ItemTemplate::get_scale_z() const { return _scale_z; } void ItemTemplate::set_scale_z(const float value) { _scale_z = value; } int ItemTemplate::get_bag_size() const { return _bag_size; } void ItemTemplate::set_bag_size(const int size) { _bag_size = size; } /// TEXTS //// String ItemTemplate::get_text_translation_key() const { return _text_translation_key; } void ItemTemplate::set_text_translation_key(const String &value) { _text_translation_key = value; } //// TEACHES //// int ItemTemplate::get_num_teaches_spells() const { return _teaches_spells.size(); } void ItemTemplate::set_num_teaches_spells(int value) { _teaches_spells.resize(value); } Ref ItemTemplate::get_teaches_spell(const int index) { ERR_FAIL_INDEX_V(index, _teaches_spells.size(), Ref()); return _teaches_spells[index]; } void ItemTemplate::set_teaches_spell(const int index, const Ref &spell) { ERR_FAIL_INDEX(index, _teaches_spells.size()); _teaches_spells.set(index, Ref(spell)); } Vector ItemTemplate::get_teaches_spells() { VARIANT_ARRAY_GET(_teaches_spells); } void ItemTemplate::set_teaches_spells(const Vector &spells) { VARIANT_ARRAY_SET(spells, _teaches_spells, Spell); } //// GRANTS SPELLS //// int ItemTemplate::get_num_grants_spells() const { return _grants_spells.size(); } void ItemTemplate::set_num_grants_spells(const int value) { _grants_spells.resize(value); } Ref ItemTemplate::get_grants_spell(const int index) { ERR_FAIL_INDEX_V(index, _grants_spells.size(), Ref()); return _grants_spells[index]; } void ItemTemplate::set_grants_spell(const int index, const Ref &spell) { ERR_FAIL_INDEX(index, _grants_spells.size()); _grants_spells.set(index, Ref(spell)); } Vector ItemTemplate::get_grants_spells() { VARIANT_ARRAY_GET(_grants_spells); } void ItemTemplate::set_grants_spells(const Vector &spells) { VARIANT_ARRAY_SET(spells, _grants_spells, Spell); } //// AURAS //// int ItemTemplate::get_num_auras() const { return _auras.size(); } void ItemTemplate::set_num_auras(int value) { _auras.resize(value); } Ref ItemTemplate::get_aura(const int index) { ERR_FAIL_INDEX_V(index, _auras.size(), Ref()); return _auras[index]; } void ItemTemplate::set_aura(const int index, const Ref &aura) { ERR_FAIL_INDEX(index, _auras.size()); _auras.set(index, Ref(aura)); } Vector ItemTemplate::get_auras() { VARIANT_ARRAY_GET(_auras); } void ItemTemplate::set_auras(const Vector &auras) { VARIANT_ARRAY_SET(auras, _auras, Spell); } //Required Skills int ItemTemplate::get_num_required_skills() const { return _required_skills.size(); } Ref ItemTemplate::get_required_skill(const int index) { ERR_FAIL_INDEX_V(index, _required_skills.size(), Ref()); return _required_skills.get(index); } void ItemTemplate::set_required_skill(const int index, const Ref &aura) { ERR_FAIL_INDEX(index, _required_skills.size()); _required_skills.set(index, aura); } Vector ItemTemplate::get_required_skills() { VARIANT_ARRAY_GET(_required_skills); } void ItemTemplate::set_required_skills(const Vector &skills) { VARIANT_ARRAY_SET(skills, _required_skills, Spell); } //use spell Ref ItemTemplate::get_use_spell() { return _use_spell; } void ItemTemplate::set_use_spell(const Ref &use_spell) { _use_spell = use_spell; } int ItemTemplate::get_charges() const { return _charges; } void ItemTemplate::set_charges(const int value) { _charges = value; } bool ItemTemplate::get_consumed() const { return _consumed; } void ItemTemplate::set_consumed(const bool value) { _consumed = false; } int ItemTemplate::stat_modifier_get_count() const { return _modifier_count; } void ItemTemplate::stat_modifier_set_count(int value) { _modifier_count = value; } int ItemTemplate::stat_modifier_get_stat_id(const int index) const { return _modifiers[index].stat_id; } void ItemTemplate::stat_modifier_set_stat_id(const int index, const int value) { _modifiers[index].stat_id = value; } float ItemTemplate::stat_modifier_get_min_base_mod(const int index) const { return _modifiers[index].min_base_mod; } void ItemTemplate::stat_modifier_set_min_base_mod(const int index, const float value) { _modifiers[index].min_base_mod = value; } float ItemTemplate::stat_modifier_get_max_base_mod(const int index) const { return _modifiers[index].max_base_mod; } void ItemTemplate::stat_modifier_set_max_base_mod(const int index, const float value) { _modifiers[index].max_base_mod = value; } float ItemTemplate::stat_modifier_get_min_bonus_mod(const int index) const { return _modifiers[index].min_bonus_mod; } void ItemTemplate::stat_modifier_set_min_bonus_mod(const int index, const float value) { _modifiers[index].min_bonus_mod = value; } float ItemTemplate::stat_modifier_get_max_bonus_mod(const int index) const { return _modifiers[index].max_bonus_mod; } void ItemTemplate::stat_modifier_set_max_bonus_mod(const int index, const float value) { _modifiers[index].max_bonus_mod = value; } float ItemTemplate::stat_modifier_get_min_percent_mod(const int index) const { return _modifiers[index].min_percent_mod; } void ItemTemplate::stat_modifier_set_min_percent_mod(const int index, const float value) { _modifiers[index].min_percent_mod = value; } float ItemTemplate::stat_modifier_get_max_percent_mod(const int index) const { return _modifiers[index].max_percent_mod; } void ItemTemplate::stat_modifier_set_max_percent_mod(const int index, const float value) { _modifiers[index].max_percent_mod = value; } float ItemTemplate::stat_modifier_get_scaling_factor(const int index) const { return _modifiers[index].scaling_factor; } void ItemTemplate::stat_modifier_set_scaling_factor(const int index, const float value) { _modifiers[index].scaling_factor = value; } int ItemTemplate::get_animator_weapon_type() { if (_item_sub_type == ItemEnums::ITEM_SUB_TYPE_SWORD) { return 1; } if (_item_sub_type == ItemEnums::ITEM_SUB_TYPE_BOW) { return 2; } if (_item_sub_type == ItemEnums::ITEM_SUB_TYPE_AXE) { return 3; } return 0; } Ref ItemTemplate::create_item_instance() { if (has_method("_create_item_instance")) { Ref ii = call("_create_item_instance"); ERR_FAIL_COND_V(!ii.is_valid(), Ref()); return ii; } Ref item; item.instantiate(); //todo setup //ERR_EXPLAIN("NOT YET IMPLEMENTED!"); ERR_FAIL_V(item); return item; } String ItemTemplate::get_description() { if (!has_method("_get_description")) return ""; return call("_get_description"); } ItemTemplate::ItemTemplate() { _id = 0; _item_type = ItemEnums::ITEM_TYPE_NONE; _item_sub_type = ItemEnums::ITEM_SUB_TYPE_NONE; _item_sub_sub_type = ItemEnums::ITEM_SUB_SUB_TYPE_NONE; _rarity = ItemEnums::ITEM_RARITY_NONE; _armor_type = ItemEnums::ARMOR_TYPE_NONE; _equip_slot = ESS::get_singleton()->equip_slot_get_count(); _price = 0; _scale_x = 0; _scale_y = 0; _scale_z = 0; _modifier_count = 0; _stack_size = 1; _bag_size = 0; _charges = -1; _consumed = false; } ItemTemplate::~ItemTemplate() { _teaches_spells.clear(); _grants_spells.clear(); _auras.clear(); _required_character_class.unref(); } void ItemTemplate::_validate_property(PropertyInfo &property) const { String prop = property.name; if (prop.begins_with("stat_modifier_")) { if (prop.ends_with("count")) return; int frame = prop.get_slicec('/', 0).get_slicec('_', 2).to_int(); if (frame >= _modifier_count) { property.usage = 0; } if (property.name.ends_with("stat_id")) property.hint_string = ESS::get_singleton()->stat_get_string(); } else if (prop == "equip_slot") { property.hint_string = ESS::get_singleton()->equip_slot_get_string(); } } void ItemTemplate::_bind_methods() { ////GDVIRTUAL_BIND("_create_item_instance"); ClassDB::bind_method(D_METHOD("create_item_instance"), &ItemTemplate::create_item_instance); ClassDB::bind_method(D_METHOD("get_id"), &ItemTemplate::get_id); ClassDB::bind_method(D_METHOD("set_id", "count"), &ItemTemplate::set_id); ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id"); ClassDB::bind_method(D_METHOD("get_item_type"), &ItemTemplate::get_item_type); ClassDB::bind_method(D_METHOD("set_item_type", "count"), &ItemTemplate::set_item_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "item_type", PROPERTY_HINT_ENUM, ItemEnums::BINDING_STRING_ITEM_TYPE), "set_item_type", "get_item_type"); ClassDB::bind_method(D_METHOD("get_item_sub_type"), &ItemTemplate::get_item_sub_type); ClassDB::bind_method(D_METHOD("set_item_sub_type", "count"), &ItemTemplate::set_item_sub_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "item_sub_type", PROPERTY_HINT_ENUM, ItemEnums::BINDING_STRING_ITEM_SUB_TYPE), "set_item_sub_type", "get_item_sub_type"); ClassDB::bind_method(D_METHOD("get_item_sub_sub_type"), &ItemTemplate::get_item_sub_sub_type); ClassDB::bind_method(D_METHOD("set_item_sub_sub_type", "count"), &ItemTemplate::set_item_sub_sub_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "item_sub_sub_type", PROPERTY_HINT_ENUM, ItemEnums::BINDING_STRING_ITEM_SUB_SUB_TYPE), "set_item_sub_sub_type", "get_item_sub_sub_type"); ClassDB::bind_method(D_METHOD("get_rarity"), &ItemTemplate::get_rarity); ClassDB::bind_method(D_METHOD("set_rarity", "count"), &ItemTemplate::set_rarity); ADD_PROPERTY(PropertyInfo(Variant::INT, "rarity", PROPERTY_HINT_ENUM, ItemEnums::BINDING_STRING_RARITY), "set_rarity", "get_rarity"); ClassDB::bind_method(D_METHOD("get_armor_type"), &ItemTemplate::get_armor_type); ClassDB::bind_method(D_METHOD("set_armor_type", "value"), &ItemTemplate::set_armor_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "armor_type", PROPERTY_HINT_ENUM, ItemEnums::BINDING_STRING_ARMOR_TYPE), "set_armor_type", "get_armor_type"); ClassDB::bind_method(D_METHOD("get_equip_slot"), &ItemTemplate::get_equip_slot); ClassDB::bind_method(D_METHOD("set_equip_slot", "count"), &ItemTemplate::set_equip_slot); ADD_PROPERTY(PropertyInfo(Variant::INT, "equip_slot", PROPERTY_HINT_ENUM, ""), "set_equip_slot", "get_equip_slot"); ClassDB::bind_method(D_METHOD("get_price"), &ItemTemplate::get_price); ClassDB::bind_method(D_METHOD("set_price", "count"), &ItemTemplate::set_price); ADD_PROPERTY(PropertyInfo(Variant::INT, "price"), "set_price", "get_price"); ClassDB::bind_method(D_METHOD("get_model_visual"), &ItemTemplate::get_model_visual); ClassDB::bind_method(D_METHOD("set_model_visual", "value"), &ItemTemplate::set_model_visual); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "model_visual", PROPERTY_HINT_RESOURCE_TYPE, "ModelVisual"), "set_model_visual", "get_model_visual"); ClassDB::bind_method(D_METHOD("get_stack_size"), &ItemTemplate::get_stack_size); ClassDB::bind_method(D_METHOD("set_stack_size", "value"), &ItemTemplate::set_stack_size); ADD_PROPERTY(PropertyInfo(Variant::INT, "stack_size"), "set_stack_size", "get_stack_size"); ClassDB::bind_method(D_METHOD("get_icon"), &ItemTemplate::get_icon); ClassDB::bind_method(D_METHOD("set_icon", "value"), &ItemTemplate::set_icon); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_icon", "get_icon"); ClassDB::bind_method(D_METHOD("get_scale_x"), &ItemTemplate::get_scale_x); ClassDB::bind_method(D_METHOD("set_scale_x", "count"), &ItemTemplate::set_scale_x); ADD_PROPERTY(PropertyInfo(Variant::REAL, "scale_x"), "set_scale_x", "get_scale_x"); ClassDB::bind_method(D_METHOD("get_scale_y"), &ItemTemplate::get_scale_y); ClassDB::bind_method(D_METHOD("set_scale_y", "count"), &ItemTemplate::set_scale_y); ADD_PROPERTY(PropertyInfo(Variant::REAL, "scale_y"), "set_scale_y", "get_scale_y"); ClassDB::bind_method(D_METHOD("get_scale_z"), &ItemTemplate::get_scale_z); ClassDB::bind_method(D_METHOD("set_scale_z", "count"), &ItemTemplate::set_scale_z); ADD_PROPERTY(PropertyInfo(Variant::REAL, "scale_z"), "set_scale_z", "get_scale_z"); ClassDB::bind_method(D_METHOD("get_bag_size"), &ItemTemplate::get_bag_size); ClassDB::bind_method(D_METHOD("set_bag_size", "size"), &ItemTemplate::set_bag_size); ADD_PROPERTY(PropertyInfo(Variant::INT, "bag_size"), "set_bag_size", "get_bag_size"); //// Teaches //// ClassDB::bind_method(D_METHOD("get_num_teaches_spells"), &ItemTemplate::get_num_teaches_spells); ClassDB::bind_method(D_METHOD("set_num_teaches_spells", "value"), &ItemTemplate::set_num_teaches_spells); ClassDB::bind_method(D_METHOD("get_teaches_spell", "index"), &ItemTemplate::get_teaches_spell); ClassDB::bind_method(D_METHOD("set_teaches_spell", "index", "spell"), &ItemTemplate::set_teaches_spell); ClassDB::bind_method(D_METHOD("get_teaches_spells"), &ItemTemplate::get_teaches_spells); ClassDB::bind_method(D_METHOD("set_teaches_spells", "spells"), &ItemTemplate::set_teaches_spells); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "teaches_spells", PROPERTY_HINT_NONE, "17/17:Spell", PROPERTY_USAGE_DEFAULT, "Spell"), "set_teaches_spells", "get_teaches_spells"); //// Grants Spells //// ClassDB::bind_method(D_METHOD("get_num_grants_spells"), &ItemTemplate::get_num_grants_spells); ClassDB::bind_method(D_METHOD("set_num_grants_spells", "value"), &ItemTemplate::set_num_grants_spells); ClassDB::bind_method(D_METHOD("get_grants_spell", "index"), &ItemTemplate::get_grants_spell); ClassDB::bind_method(D_METHOD("set_grants_spell", "index", "spell"), &ItemTemplate::set_grants_spell); ClassDB::bind_method(D_METHOD("get_grants_spells"), &ItemTemplate::get_grants_spells); ClassDB::bind_method(D_METHOD("set_grants_spells", "spells"), &ItemTemplate::set_grants_spells); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "grants_spells", PROPERTY_HINT_NONE, "17/17:Spell", PROPERTY_USAGE_DEFAULT, "Spell"), "set_grants_spells", "get_grants_spells"); //// Auras //// ClassDB::bind_method(D_METHOD("get_num_auras"), &ItemTemplate::get_num_auras); ClassDB::bind_method(D_METHOD("set_num_auras", "value"), &ItemTemplate::set_num_auras); ClassDB::bind_method(D_METHOD("get_aura", "index"), &ItemTemplate::get_aura); ClassDB::bind_method(D_METHOD("set_aura", "index", "aura"), &ItemTemplate::set_aura); ClassDB::bind_method(D_METHOD("get_auras"), &ItemTemplate::get_auras); ClassDB::bind_method(D_METHOD("set_auras", "auras"), &ItemTemplate::set_auras); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "auras", PROPERTY_HINT_NONE, "17/17:Spell", PROPERTY_USAGE_DEFAULT, "Spell"), "set_auras", "get_auras"); //// Required Skills //// ClassDB::bind_method(D_METHOD("get_num_required_skills"), &ItemTemplate::get_num_required_skills); ClassDB::bind_method(D_METHOD("get_required_skill", "index"), &ItemTemplate::get_required_skill); ClassDB::bind_method(D_METHOD("set_required_skill", "index", "aura"), &ItemTemplate::set_required_skill); ClassDB::bind_method(D_METHOD("get_required_skills"), &ItemTemplate::get_required_skills); ClassDB::bind_method(D_METHOD("set_required_skills", "auras"), &ItemTemplate::set_required_skills); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "required_skills", PROPERTY_HINT_NONE, "17/17:Spell", PROPERTY_USAGE_DEFAULT, "Spell"), "set_required_skills", "get_required_skills"); //Use spell ClassDB::bind_method(D_METHOD("get_use_spell"), &ItemTemplate::get_use_spell); ClassDB::bind_method(D_METHOD("set_use_spell", "size"), &ItemTemplate::set_use_spell); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "use_spell", PROPERTY_HINT_RESOURCE_TYPE, "Spell"), "set_use_spell", "get_use_spell"); ClassDB::bind_method(D_METHOD("get_charges"), &ItemTemplate::get_charges); ClassDB::bind_method(D_METHOD("set_charges", "size"), &ItemTemplate::set_charges); ADD_PROPERTY(PropertyInfo(Variant::INT, "charges"), "set_charges", "get_charges"); ClassDB::bind_method(D_METHOD("get_consumed"), &ItemTemplate::get_consumed); ClassDB::bind_method(D_METHOD("set_consumed", "size"), &ItemTemplate::set_consumed); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "consumed"), "set_consumed", "get_consumed"); ADD_GROUP("Texts", "text"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text_name"), "set_name", "get_name"); ClassDB::bind_method(D_METHOD("get_text_translation_key"), &ItemTemplate::get_text_translation_key); ClassDB::bind_method(D_METHOD("set_text_translation_key", "value"), &ItemTemplate::set_text_translation_key); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text_translation_key"), "set_text_translation_key", "get_text_translation_key"); ////GDVIRTUAL_BIND("_get_description"); ClassDB::bind_method(D_METHOD("get_description"), &ItemTemplate::get_description); //StatMods Property binds ADD_GROUP("Stat Modifiers", "stat_modifier"); ClassDB::bind_method(D_METHOD("stat_modifier_get_count"), &ItemTemplate::stat_modifier_get_count); ClassDB::bind_method(D_METHOD("stat_modifier_set_count", "count"), &ItemTemplate::stat_modifier_set_count); ADD_PROPERTY(PropertyInfo(Variant::INT, "stat_modifier_count", PROPERTY_HINT_RANGE, "0," + itos(MAX_ITEM_STAT_MOD), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "stat_modifier_set_count", "stat_modifier_get_count"); ClassDB::bind_method(D_METHOD("stat_modifier_get_stat_id", "index"), &ItemTemplate::stat_modifier_get_stat_id); ClassDB::bind_method(D_METHOD("stat_modifier_set_stat_id", "index", "value"), &ItemTemplate::stat_modifier_set_stat_id); ClassDB::bind_method(D_METHOD("stat_modifier_get_min_base_mod", "index"), &ItemTemplate::stat_modifier_get_min_base_mod); ClassDB::bind_method(D_METHOD("stat_modifier_set_min_base_mod", "index", "value"), &ItemTemplate::stat_modifier_set_min_base_mod); ClassDB::bind_method(D_METHOD("stat_modifier_get_max_base_mod", "index"), &ItemTemplate::stat_modifier_get_max_base_mod); ClassDB::bind_method(D_METHOD("stat_modifier_set_max_base_mod", "index", "value"), &ItemTemplate::stat_modifier_set_max_base_mod); ClassDB::bind_method(D_METHOD("stat_modifier_get_min_bonus_mod", "index"), &ItemTemplate::stat_modifier_get_min_bonus_mod); ClassDB::bind_method(D_METHOD("stat_modifier_set_min_bonus_mod", "index", "value"), &ItemTemplate::stat_modifier_set_min_bonus_mod); ClassDB::bind_method(D_METHOD("stat_modifier_get_max_bonus_mod", "index"), &ItemTemplate::stat_modifier_get_max_bonus_mod); ClassDB::bind_method(D_METHOD("stat_modifier_set_max_bonus_mod", "index", "value"), &ItemTemplate::stat_modifier_set_max_bonus_mod); ClassDB::bind_method(D_METHOD("stat_modifier_get_min_percent_mod", "index"), &ItemTemplate::stat_modifier_get_min_percent_mod); ClassDB::bind_method(D_METHOD("stat_modifier_set_min_percent_mod", "index", "value"), &ItemTemplate::stat_modifier_set_min_percent_mod); ClassDB::bind_method(D_METHOD("stat_modifier_get_max_percent_mod", "index"), &ItemTemplate::stat_modifier_get_max_percent_mod); ClassDB::bind_method(D_METHOD("stat_modifier_set_max_percent_mod", "index", "value"), &ItemTemplate::stat_modifier_set_max_percent_mod); ClassDB::bind_method(D_METHOD("stat_modifier_get_scaling_factor", "index"), &ItemTemplate::stat_modifier_get_scaling_factor); ClassDB::bind_method(D_METHOD("stat_modifier_set_scaling_factor", "index", "value"), &ItemTemplate::stat_modifier_set_scaling_factor); for (int i = 0; i < MAX_ITEM_STAT_MOD; ++i) { ADD_PROPERTYI(PropertyInfo(Variant::INT, "stat_modifier_" + itos(i) + "/stat_id", PROPERTY_HINT_ENUM, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "stat_modifier_set_stat_id", "stat_modifier_get_stat_id", i); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "stat_modifier_" + itos(i) + "/min_base_mod", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "stat_modifier_set_min_base_mod", "stat_modifier_get_min_base_mod", i); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "stat_modifier_" + itos(i) + "/max_base_mod", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "stat_modifier_set_max_base_mod", "stat_modifier_get_max_base_mod", i); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "stat_modifier_" + itos(i) + "/min_bonus_mod", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "stat_modifier_set_min_bonus_mod", "stat_modifier_get_min_bonus_mod", i); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "stat_modifier_" + itos(i) + "/max_bonus_mod", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "stat_modifier_set_max_bonus_mod", "stat_modifier_get_max_bonus_mod", i); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "stat_modifier_" + itos(i) + "/min_percent_mod", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "stat_modifier_set_min_percent_mod", "stat_modifier_get_min_percent_mod", i); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "stat_modifier_" + itos(i) + "/max_percent_mod", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "stat_modifier_set_max_percent_mod", "stat_modifier_get_max_percent_mod", i); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "stat_modifier_" + itos(i) + "/scaling_factor", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "stat_modifier_set_scaling_factor", "stat_modifier_get_scaling_factor", i); } ClassDB::bind_method(D_METHOD("get_animator_weapon_type"), &ItemTemplate::get_animator_weapon_type); BIND_CONSTANT(MAX_ITEM_STAT_MOD); } ================================================ FILE: data/items/item_template.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef ITEM_TEMPLATE_H #define ITEM_TEMPLATE_H #include "core/version.h" #include "core/io/resource.h" #include "core/templates/vector.h" #include "scene/resources/texture.h" #include "../../item_enums.h" #include "model_visual.h" class ItemInstance; class Spell; class EntityClassData; class ItemTemplate : public Resource { GDCLASS(ItemTemplate, Resource); public: int get_id() const; void set_id(const int value); ItemEnums::ItemType get_item_type() const; void set_item_type(const ItemEnums::ItemType value); ItemEnums::ItemSubtype get_item_sub_type() const; void set_item_sub_type(const ItemEnums::ItemSubtype value); ItemEnums::ItemSubSubtype get_item_sub_sub_type() const; void set_item_sub_sub_type(const ItemEnums::ItemSubSubtype value); ItemEnums::ItemRarity get_rarity() const; void set_rarity(const ItemEnums::ItemRarity value); ItemEnums::ArmorType get_armor_type() const; void set_armor_type(const ItemEnums::ArmorType value); int get_equip_slot() const; void set_equip_slot(const int value); Ref get_model_visual() const; void set_model_visual(const Ref &value); Ref get_required_character_class() const; void set_required_character_class(const Ref &value); int get_price() const; void set_price(const int value); int get_stack_size() const; void set_stack_size(const int value); Ref get_icon() const; void set_icon(const Ref &value); float get_scale_x() const; void set_scale_x(const float value); float get_scale_y() const; void set_scale_y(const float value); float get_scale_z() const; void set_scale_z(const float value); int get_bag_size() const; void set_bag_size(const int size); String get_text_translation_key() const; void set_text_translation_key(const String &value); //Teaches int get_num_teaches_spells() const; void set_num_teaches_spells(const int value); Ref get_teaches_spell(const int index); void set_teaches_spell(const int index, const Ref &teaches_spell); Vector get_teaches_spells(); void set_teaches_spells(const Vector &teaches_spells); //Grants Spells int get_num_grants_spells() const; void set_num_grants_spells(const int value); Ref get_grants_spell(const int index); void set_grants_spell(const int index, const Ref &grants_spell); Vector get_grants_spells(); void set_grants_spells(const Vector &grants_spells); //Auras int get_num_auras() const; void set_num_auras(const int value); Ref get_aura(const int index); void set_aura(const int index, const Ref &aura); Vector get_auras(); void set_auras(const Vector &auras); //Required Skills int get_num_required_skills() const; Ref get_required_skill(const int index); void set_required_skill(const int index, const Ref &skills); Vector get_required_skills(); void set_required_skills(const Vector &grants_spells); //use spell Ref get_use_spell(); void set_use_spell(const Ref &use_spell); int get_charges() const; void set_charges(const int value); bool get_consumed() const; void set_consumed(const bool value); //Stat mods int stat_modifier_get_count() const; void stat_modifier_set_count(const int value); int stat_modifier_get_stat_id(int index) const; void stat_modifier_set_stat_id(int index, int value); float stat_modifier_get_min_base_mod(const int index) const; void stat_modifier_set_min_base_mod(const int index, const float value); float stat_modifier_get_max_base_mod(const int index) const; void stat_modifier_set_max_base_mod(const int index, const float value); float stat_modifier_get_min_bonus_mod(const int index) const; void stat_modifier_set_min_bonus_mod(const int index, const float value); float stat_modifier_get_max_bonus_mod(const int index) const; void stat_modifier_set_max_bonus_mod(const int index, const float value); float stat_modifier_get_min_percent_mod(const int index) const; void stat_modifier_set_min_percent_mod(const int index, const float value); float stat_modifier_get_max_percent_mod(const int index) const; void stat_modifier_set_max_percent_mod(const int index, const float value); float stat_modifier_get_scaling_factor(const int index) const; void stat_modifier_set_scaling_factor(const int index, const float value); int get_animator_weapon_type(); Ref create_item_instance(); String get_description(); ItemTemplate(); ~ItemTemplate(); public: struct SkillEntry { Ref aura; int level; }; protected: void _validate_property(PropertyInfo &property) const; static void _bind_methods(); protected: struct ItemTemplateStatModifier { int stat_id; float min_base_mod; float max_base_mod; float min_bonus_mod; float max_bonus_mod; float min_percent_mod; float max_percent_mod; float scaling_factor; ItemTemplateStatModifier() { stat_id = 0; min_base_mod = 0; max_base_mod = 0; min_bonus_mod = 0; max_bonus_mod = 0; min_percent_mod = 0; max_percent_mod = 0; scaling_factor = 1; } }; private: enum { MAX_ITEM_STAT_MOD = 6, }; int _id; ItemEnums::ItemRarity _rarity; ItemEnums::ItemType _item_type; ItemEnums::ItemSubtype _item_sub_type; ItemEnums::ItemSubSubtype _item_sub_sub_type; ItemEnums::ArmorType _armor_type; int _equip_slot; int _price; Ref _required_character_class; Ref _model_visual; int _stack_size; Ref _icon; float _scale_x; float _scale_y; float _scale_z; int _bag_size; String _text_translation_key; Vector > _teaches_spells; Vector > _grants_spells; Vector > _auras; Vector > _required_skills; Ref _use_spell; int _charges; bool _consumed; int _modifier_count; ItemTemplateStatModifier _modifiers[MAX_ITEM_STAT_MOD]; }; #endif ================================================ FILE: data/items/model_visual.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "model_visual.h" #include "../../singletons/ess.h" #include "../../defines.h" int ModelVisual::get_layer() { return _layer; } void ModelVisual::set_layer(int layer) { _layer = layer; } //ModelVisualEntries Ref ModelVisual::get_visual_entry(const int index) const { ERR_FAIL_INDEX_V(index, _visual_entries.size(), Ref()); return _visual_entries.get(index); } void ModelVisual::set_visual_entry(const int index, const Ref visual_entry) { ERR_FAIL_INDEX(index, _visual_entries.size()); _visual_entries.set(index, visual_entry); } void ModelVisual::add_visual_entry(const Ref visual_entry) { _visual_entries.push_back(visual_entry); } void ModelVisual::remove_visual_entry(const int index) { ERR_FAIL_INDEX(index, _visual_entries.size()); _visual_entries.remove_at(index); } int ModelVisual::get_visual_entry_count() const { return _visual_entries.size(); } Vector ModelVisual::get_visual_entries() { VARIANT_ARRAY_GET(_visual_entries); } void ModelVisual::set_visual_entries(const Vector &visual_entries) { VARIANT_ARRAY_SET(visual_entries, _visual_entries, ModelVisualEntry); } ModelVisual::ModelVisual() { _layer = 0; } ModelVisual::~ModelVisual() { _visual_entries.clear(); } void ModelVisual::_validate_property(PropertyInfo &property) const { String name = property.name; if (name == "layer") { property.hint_string = ESS::get_singleton()->texture_layers_get(); } } void ModelVisual::_bind_methods() { ClassDB::bind_method(D_METHOD("get_layer"), &ModelVisual::get_layer); ClassDB::bind_method(D_METHOD("set_layer", "layer"), &ModelVisual::set_layer); ADD_PROPERTY(PropertyInfo(Variant::INT, "layer", PROPERTY_HINT_ENUM, ""), "set_layer", "get_layer"); //ModelVisualEntry ClassDB::bind_method(D_METHOD("get_visual_entry", "index"), &ModelVisual::get_visual_entry); ClassDB::bind_method(D_METHOD("set_visual_entry", "index", "data"), &ModelVisual::set_visual_entry); ClassDB::bind_method(D_METHOD("add_visual_entry", "visual_entry"), &ModelVisual::add_visual_entry); ClassDB::bind_method(D_METHOD("remove_visual_entry", "index"), &ModelVisual::remove_visual_entry); ClassDB::bind_method(D_METHOD("get_visual_entry_count"), &ModelVisual::get_visual_entry_count); ClassDB::bind_method(D_METHOD("get_visual_entries"), &ModelVisual::get_visual_entries); ClassDB::bind_method(D_METHOD("set_visual_entries", "visual_entrys"), &ModelVisual::set_visual_entries); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "get_visual_entries", PROPERTY_HINT_NONE, "17/17:ModelVisualEntry", PROPERTY_USAGE_DEFAULT, "ModelVisualEntry"), "set_visual_entries", "get_visual_entries"); } ================================================ FILE: data/items/model_visual.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef MODEL_VISUAL_H #define MODEL_VISUAL_H #include "core/version.h" #include "core/io/resource.h" #include "../../item_enums.h" #include "model_visual_entry.h" class ModelVisual : public Resource { GDCLASS(ModelVisual, Resource); public: int get_layer(); void set_layer(int layer); //ModelVisualEntry Ref get_visual_entry(const int index) const; void set_visual_entry(const int index, const Ref visual_entry); void add_visual_entry(const Ref visual_entry); void remove_visual_entry(const int index); int get_visual_entry_count() const; Vector get_visual_entries(); void set_visual_entries(const Vector &visual_entries); ModelVisual(); ~ModelVisual(); protected: void _validate_property(PropertyInfo &property) const; static void _bind_methods(); private: int _layer; Vector > _visual_entries; }; #endif ================================================ FILE: data/items/model_visual_entry.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "model_visual_entry.h" #include "../../singletons/ess.h" const String ModelVisualEntry::BINDING_STRING_MODEL_VISUAL_ENTRY_TYPES = "Bone,Attachment"; ModelVisualEntry::ModenVisualEntryType ModelVisualEntry::get_type() const { return _type; } void ModelVisualEntry::set_type(const ModelVisualEntry::ModenVisualEntryType type) { _type = type; } int ModelVisualEntry::get_override_layer() const { return _override_layer; } void ModelVisualEntry::set_override_layer(const int layer) { _override_layer = layer; } int ModelVisualEntry::get_entity_type() const { return _entity_type; } void ModelVisualEntry::set_entity_type(const int value) { _entity_type = value; } int ModelVisualEntry::get_bone() const { return _bone; } void ModelVisualEntry::set_bone(const int value) { _bone = value; } int ModelVisualEntry::get_group() const { return _group; } void ModelVisualEntry::set_group(const int value) { _group = value; } #ifdef MESH_DATA_RESOURCE_PRESENT Ref ModelVisualEntry::get_mesh(const int index) { ERR_FAIL_INDEX_V(index, _entries.size(), Ref()); return _entries[index].mesh; } void ModelVisualEntry::set_mesh(const int index, const Ref &mesh) { ERR_FAIL_INDEX(index, _entries.size()); _entries.write[index].mesh = mesh; } #endif Ref ModelVisualEntry::get_texture(const int index) { ERR_FAIL_INDEX_V(index, _entries.size(), Ref()); return _entries[index].texture; } void ModelVisualEntry::set_texture(const int index, const Ref &texture) { ERR_FAIL_INDEX(index, _entries.size()); _entries.write[index].texture = texture; } Color ModelVisualEntry::get_color(const int index) const { ERR_FAIL_INDEX_V(index, _entries.size(), Color()); return _entries[index].color; } void ModelVisualEntry::set_color(const int index, const Color &color) { ERR_FAIL_INDEX(index, _entries.size()); _entries.write[index].color = color; } Ref ModelVisualEntry::get_attachment(const int index) { ERR_FAIL_INDEX_V(index, _entries.size(), Ref()); return _entries[index].attachment; } void ModelVisualEntry::set_attachment(const int index, const Ref &attachment) { ERR_FAIL_INDEX(index, _entries.size()); _entries.write[index].attachment = attachment; } Transform3D ModelVisualEntry::get_transform(const int index) const { ERR_FAIL_INDEX_V(index, _entries.size(), Transform3D()); return _entries[index].transform; } void ModelVisualEntry::set_transform(const int index, const Transform3D &transform) { ERR_FAIL_INDEX(index, _entries.size()); _entries.write[index].transform = transform; } int ModelVisualEntry::get_size() const { return _entries.size(); } void ModelVisualEntry::set_size(const int value) { _entries.resize(value); } ModelVisualEntry::ModelVisualEntry() { _type = MODEL_VISUAL_ENTRY_TYPE_BONE; _override_layer = 0; _entity_type = 0; _bone = 0; _group = 0; _entries.resize(1); } ModelVisualEntry::~ModelVisualEntry() { _entries.clear(); } bool ModelVisualEntry::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; if (name.begins_with("entry_")) { int index = name.get_slicec('_', 1).to_int(); if (index >= _entries.size()) { _entries.resize(index + 1); } StringName p = name.get_slicec('/', 1); if (p == "texture") { _entries.write[index].texture = p_value; return true; #ifdef MESH_DATA_RESOURCE_PRESENT } else if (p == "mesh") { _entries.write[index].mesh = p_value; return true; #endif } else if (p == "color") { _entries.write[index].color = p_value; return true; } else if (p == "attachment") { _entries.write[index].attachment = p_value; return true; } else if (p == "transform") { _entries.write[index].transform = p_value; return true; } } return false; } bool ModelVisualEntry::_get(const StringName &p_name, Variant &r_ret) const { String name = p_name; if (name.begins_with("entry_")) { int index = name.get_slicec('_', 1).to_int(); if (index >= _entries.size()) { return false; } StringName p = name.get_slicec('/', 1); if (p == "texture") { r_ret = _entries[index].texture; return true; #ifdef MESH_DATA_RESOURCE_PRESENT } else if (p == "mesh") { r_ret = _entries[index].mesh; return true; #endif } else if (p == "color") { r_ret = _entries[index].color; return true; } else if (p == "attachment") { r_ret = _entries[index].attachment; return true; } else if (p == "transform") { r_ret = _entries[index].transform; return true; } } return false; } void ModelVisualEntry::_get_property_list(List *p_list) const { for (int i = 0; i < _entries.size(); ++i) { if (_type == ModelVisualEntry::MODEL_VISUAL_ENTRY_TYPE_BONE) { #ifdef MESH_DATA_RESOURCE_PRESENT p_list->push_back(PropertyInfo(Variant::OBJECT, "entry_" + itos(i) + "/mesh", PROPERTY_HINT_RESOURCE_TYPE, "MeshDataResource", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL)); #endif p_list->push_back(PropertyInfo(Variant::OBJECT, "entry_" + itos(i) + "/texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::COLOR, "entry_" + itos(i) + "/color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL)); } else { p_list->push_back(PropertyInfo(Variant::OBJECT, "entry_" + itos(i) + "/attachment", PROPERTY_HINT_RESOURCE_TYPE, "PackedScene", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL)); } p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, "entry_" + itos(i) + "/transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL)); } } void ModelVisualEntry::_validate_property(PropertyInfo &property) const { String name = property.name; if (_type == ModelVisualEntry::MODEL_VISUAL_ENTRY_TYPE_BONE) { if (name == "entity_type") { property.usage = PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED; property.hint_string = ESS::get_singleton()->entity_types_get(); } else if (name == "bone") { if (ESS::get_singleton()->skeletons_bones_count() > _entity_type) { property.hint_string = ESS::get_singleton()->skeletons_bones_index_get(_entity_type); } else { property.hint_string = ""; } } } else { if (name == "entity_type") { property.usage = PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED; } else if (name == "bone") { property.hint_string = EntityEnums::BINDING_STRING_COMMON_CHARCATER_SKELETON_POINTS; } } if (name == "group") { property.hint_string = ESS::get_singleton()->model_visual_groups_get(); } else if (name == "override_layer") { property.hint_string = ESS::get_singleton()->texture_layers_get(); } } void ModelVisualEntry::_bind_methods() { ClassDB::bind_method(D_METHOD("get_type"), &ModelVisualEntry::get_type); ClassDB::bind_method(D_METHOD("set_type", "value"), &ModelVisualEntry::set_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, ModelVisualEntry::BINDING_STRING_MODEL_VISUAL_ENTRY_TYPES, PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_type", "get_type"); ClassDB::bind_method(D_METHOD("get_override_layer"), &ModelVisualEntry::get_override_layer); ClassDB::bind_method(D_METHOD("set_override_layer", "value"), &ModelVisualEntry::set_override_layer); ADD_PROPERTY(PropertyInfo(Variant::INT, "override_layer", PROPERTY_HINT_ENUM, ""), "set_override_layer", "get_override_layer"); ClassDB::bind_method(D_METHOD("get_entity_type"), &ModelVisualEntry::get_entity_type); ClassDB::bind_method(D_METHOD("set_entity_type", "value"), &ModelVisualEntry::set_entity_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "entity_type", PROPERTY_HINT_ENUM, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_entity_type", "get_entity_type"); ClassDB::bind_method(D_METHOD("get_bone"), &ModelVisualEntry::get_bone); ClassDB::bind_method(D_METHOD("set_bone", "value"), &ModelVisualEntry::set_bone); ADD_PROPERTY(PropertyInfo(Variant::INT, "bone", PROPERTY_HINT_ENUM), "set_bone", "get_bone"); ClassDB::bind_method(D_METHOD("get_group"), &ModelVisualEntry::get_group); ClassDB::bind_method(D_METHOD("set_group", "value"), &ModelVisualEntry::set_group); ADD_PROPERTY(PropertyInfo(Variant::INT, "group", PROPERTY_HINT_ENUM), "set_group", "get_group"); #ifdef MESH_DATA_RESOURCE_PRESENT ClassDB::bind_method(D_METHOD("get_mesh", "index"), &ModelVisualEntry::get_mesh); ClassDB::bind_method(D_METHOD("set_mesh", "index", "value"), &ModelVisualEntry::set_mesh); #endif ClassDB::bind_method(D_METHOD("get_texture", "index"), &ModelVisualEntry::get_texture); ClassDB::bind_method(D_METHOD("set_texture", "index", "value"), &ModelVisualEntry::set_texture); ClassDB::bind_method(D_METHOD("get_color"), &ModelVisualEntry::get_color); ClassDB::bind_method(D_METHOD("set_color", "value"), &ModelVisualEntry::set_color); ClassDB::bind_method(D_METHOD("get_attachment"), &ModelVisualEntry::get_attachment); ClassDB::bind_method(D_METHOD("set_attachment", "value"), &ModelVisualEntry::set_attachment); ClassDB::bind_method(D_METHOD("get_transform", "index"), &ModelVisualEntry::get_transform); ClassDB::bind_method(D_METHOD("set_transform", "index", "value"), &ModelVisualEntry::set_transform); ClassDB::bind_method(D_METHOD("get_size"), &ModelVisualEntry::get_size); ClassDB::bind_method(D_METHOD("set_size", "value"), &ModelVisualEntry::set_size); ADD_PROPERTY(PropertyInfo(Variant::INT, "size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_size", "get_size"); BIND_ENUM_CONSTANT(MODEL_VISUAL_ENTRY_TYPE_BONE); BIND_ENUM_CONSTANT(MODEL_VISUAL_ENTRY_TYPE_ATTACHMENT); } ================================================ FILE: data/items/model_visual_entry.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef MODEL_VISUAL_ENTRY_H #define MODEL_VISUAL_ENTRY_H #include "core/version.h" #include "core/io/resource.h" #include "core/string/ustring.h" #include "core/math/color.h" #include "scene/resources/texture.h" #include "../../entity_enums.h" #include "../../item_enums.h" #include "scene/resources/mesh.h" #include "scene/resources/packed_scene.h" #ifdef MESH_DATA_RESOURCE_PRESENT #include "../../../mesh_data_resource/mesh_data_resource.h" #endif class ModelVisualEntry : public Resource { GDCLASS(ModelVisualEntry, Resource); public: enum ModenVisualEntryType { MODEL_VISUAL_ENTRY_TYPE_BONE = 0, MODEL_VISUAL_ENTRY_TYPE_ATTACHMENT }; static const String BINDING_STRING_MODEL_VISUAL_ENTRY_TYPES; public: ModelVisualEntry::ModenVisualEntryType get_type() const; void set_type(const ModelVisualEntry::ModenVisualEntryType type); int get_override_layer() const; void set_override_layer(const int layer); int get_entity_type() const; void set_entity_type(const int value); int get_bone() const; void set_bone(const int value); int get_group() const; void set_group(const int value); #ifdef MESH_DATA_RESOURCE_PRESENT Ref get_mesh(const int index); void set_mesh(const int index, const Ref &mesh); #endif Ref get_texture(const int index); void set_texture(const int index, const Ref &texture); Color get_color(const int index) const; void set_color(const int index, const Color &color); Ref get_attachment(const int index); void set_attachment(const int index, const Ref &attachment); Transform3D get_transform(const int index) const; void set_transform(const int index, const Transform3D &transform); int get_size() const; void set_size(const int value); ModelVisualEntry(); ~ModelVisualEntry(); protected: struct MVEE { #ifdef MESH_DATA_RESOURCE_PRESENT Ref mesh; #endif Ref texture; Color color; Ref attachment; Transform3D transform; MVEE() { color = Color(1, 1, 1, 1); } ~MVEE() { #ifdef MESH_DATA_RESOURCE_PRESENT mesh.unref(); #endif texture.unref(); attachment.unref(); } }; protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List *p_list) const; void _validate_property(PropertyInfo &property) const; static void _bind_methods(); private: ModelVisualEntry::ModenVisualEntryType _type; int _override_layer; int _entity_type; int _bone; int _group; Vector _entries; }; VARIANT_ENUM_CAST(ModelVisualEntry::ModenVisualEntryType); #endif ================================================ FILE: data/loot/loot_data_base.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "loot_data_base.h" #include "../../defines.h" int LootDataBase::get_loot_db_size() const { return _loot_dbs.size(); } void LootDataBase::set_loot_db_size(const float value) { _loot_dbs.resize(value); } int LootDataBase::get_items_size() const { return _items.size(); } void LootDataBase::set_items_size(const int value) { _items.resize(value); } float LootDataBase::get_loot_db_chance(const int index) const { ERR_FAIL_INDEX_V(index, _loot_dbs.size(), 0); return _loot_dbs.get(index).chance; } void LootDataBase::set_loot_db_chance(const int index, const float value) { ERR_FAIL_INDEX(index, _loot_dbs.size()); LootDBLDF l = _loot_dbs.get(index); l.chance = value; _loot_dbs.set(index, l); } Ref LootDataBase::get_loot_db(const int index) const { ERR_FAIL_INDEX_V(index, _loot_dbs.size(), 0); return _loot_dbs.get(index).loot_db; } void LootDataBase::set_loot_db(const int index, const Ref &value) { ERR_FAIL_INDEX(index, _loot_dbs.size()); LootDBLDF l = _loot_dbs.get(index); l.loot_db = value; _loot_dbs.set(index, l); } float LootDataBase::get_item_chance(const int index) const { ERR_FAIL_INDEX_V(index, _items.size(), 0); return _items.get(index).chance; } void LootDataBase::set_item_chance(const int index, const float value) { ERR_FAIL_INDEX(index, _items.size()); LootDBItem l = _items.get(index); l.chance = value; _items.set(index, l); } Ref LootDataBase::get_item(const int index) const { ERR_FAIL_INDEX_V(index, _items.size(), 0); return _items.get(index).item; } void LootDataBase::set_item(const int index, const Ref &value) { ERR_FAIL_INDEX(index, _items.size()); LootDBItem l = _items.get(index); l.item = value; _items.set(index, l); } Array LootDataBase::get_loot() { return call("_get_loot"); } Array LootDataBase::_get_loot() { Array arr; for (int i = 0; i < _loot_dbs.size(); ++i) { LootDBLDF l = _loot_dbs.get(i); if (!l.loot_db.is_valid()) continue; Math::randomize(); float val = Math::randf() * 100.0; if (val < l.chance) { arr.append(l.loot_db->get_loot()); } } for (int i = 0; i < _items.size(); ++i) { LootDBItem l = _items.get(i); if (!l.item.is_valid()) continue; Math::randomize(); float val = Math::randf() * 100.0; if (val < l.chance) { arr.append(l.item); } } return arr; } LootDataBase::LootDataBase() { } LootDataBase::~LootDataBase() { _loot_dbs.clear(); _items.clear(); } bool LootDataBase::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; if (name.begins_with("loot_dbs/")) { int index = name.get_slicec('/', 1).to_int(); String what = name.get_slicec('/', 2); if (_loot_dbs.size() <= index) { set_loot_db_size(index); } LootDBLDF ldb = _loot_dbs.get(index); if (what == "chance") { ldb.chance = p_value; _loot_dbs.set(index, ldb); return true; } else if (what == "loot_db") { ldb.loot_db = p_value; _loot_dbs.set(index, ldb); return true; } return false; } else if (name.begins_with("items/")) { int index = name.get_slicec('/', 1).to_int(); String what = name.get_slicec('/', 2); if (_items.size() <= index) { set_items_size(index); } LootDBItem ldb = _items.get(index); if (what == "chance") { ldb.chance = p_value; _items.set(index, ldb); return true; } else if (what == "item_template") { ldb.item = p_value; _items.set(index, ldb); return true; } return false; } return true; } bool LootDataBase::_get(const StringName &p_name, Variant &r_ret) const { String name = p_name; if (name.begins_with("loot_dbs/")) { int index = name.get_slicec('/', 1).to_int(); String what = name.get_slicec('/', 2); if (_loot_dbs.size() <= index) { return false; } LootDBLDF ldb = _loot_dbs.get(index); if (what == "chance") { r_ret = ldb.chance; return true; } else if (what == "loot_db") { r_ret = ldb.loot_db; return true; } return false; } else if (name.begins_with("items/")) { int index = name.get_slicec('/', 1).to_int(); String what = name.get_slicec('/', 2); if (_items.size() <= index) { return false; } LootDBItem ldb = _items.get(index); if (what == "chance") { r_ret = ldb.chance; return true; } else if (what == "item_template") { r_ret = ldb.item; return true; } return false; } return true; } void LootDataBase::_get_property_list(List *p_list) const { int property_usange = PROPERTY_USAGE_DEFAULT; for (int i = 0; i < _loot_dbs.size(); ++i) { p_list->push_back(PropertyInfo(Variant::REAL, "loot_dbs/" + itos(i) + "/chance", PROPERTY_HINT_NONE, "", property_usange)); p_list->push_back(PropertyInfo(Variant::OBJECT, "loot_dbs/" + itos(i) + "/loot_db", PROPERTY_HINT_RESOURCE_TYPE, "LootDataBase", property_usange)); } for (int i = 0; i < _items.size(); ++i) { p_list->push_back(PropertyInfo(Variant::REAL, "items/" + itos(i) + "/chance", PROPERTY_HINT_NONE, "", property_usange)); p_list->push_back(PropertyInfo(Variant::OBJECT, "items/" + itos(i) + "/item_template", PROPERTY_HINT_RESOURCE_TYPE, "ItemTemplate", property_usange)); } } void LootDataBase::_bind_methods() { ClassDB::bind_method(D_METHOD("get_loot_db_size"), &LootDataBase::get_loot_db_size); ClassDB::bind_method(D_METHOD("set_loot_db_size", "value"), &LootDataBase::set_loot_db_size); ADD_PROPERTY(PropertyInfo(Variant::INT, "loot_db_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_loot_db_size", "get_loot_db_size"); ClassDB::bind_method(D_METHOD("get_items_size"), &LootDataBase::get_items_size); ClassDB::bind_method(D_METHOD("set_items_size", "value"), &LootDataBase::set_items_size); ADD_PROPERTY(PropertyInfo(Variant::INT, "items_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_items_size", "get_items_size"); ClassDB::bind_method(D_METHOD("get_loot_db_chance", "index"), &LootDataBase::get_loot_db_chance); ClassDB::bind_method(D_METHOD("set_loot_db_chance", "index", "value"), &LootDataBase::set_loot_db_chance); ClassDB::bind_method(D_METHOD("get_loot_db", "index"), &LootDataBase::get_loot_db); ClassDB::bind_method(D_METHOD("set_loot_db", "index", "value"), &LootDataBase::set_loot_db); ClassDB::bind_method(D_METHOD("get_item_chance", "index"), &LootDataBase::get_item_chance); ClassDB::bind_method(D_METHOD("set_item_chance", "index", "value"), &LootDataBase::set_item_chance); ClassDB::bind_method(D_METHOD("get_item", "index"), &LootDataBase::get_item); ClassDB::bind_method(D_METHOD("set_item", "index", "value"), &LootDataBase::set_item); //GDVIRTUAL_BIND("_get_loot"); ClassDB::bind_method(D_METHOD("get_loot"), &LootDataBase::get_loot); ClassDB::bind_method(D_METHOD("_get_loot"), &LootDataBase::_get_loot); } ================================================ FILE: data/loot/loot_data_base.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef LOOT_DATA_BASE_H #define LOOT_DATA_BASE_H #include "core/version.h" #include "core/templates/vector.h" #include "core/variant/array.h" #include "../items/item_template.h" class LootDataBase : public Resource { GDCLASS(LootDataBase, Resource); public: int get_loot_db_size() const; void set_loot_db_size(const float value); int get_items_size() const; void set_items_size(const int value); float get_loot_db_chance(const int index) const; void set_loot_db_chance(const int index, const float value); Ref get_loot_db(const int index) const; void set_loot_db(const int index, const Ref &value); float get_item_chance(const int index) const; void set_item_chance(const int index, const float value); Ref get_item(const int index) const; void set_item(const int index, const Ref &value); Array get_loot(); Array _get_loot(); LootDataBase(); ~LootDataBase(); protected: struct LootDBLDF { float chance; Ref loot_db; LootDBLDF() { chance = 0; } }; struct LootDBItem { float chance; Ref item; LootDBItem() { chance = 0; } }; protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List *p_list) const; static void _bind_methods(); private: Vector _loot_dbs; Vector _items; }; #endif ================================================ FILE: data/species/entity_species_data.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "entity_species_data.h" #include "../spells/spell.h" #include "../../singletons/ess.h" #include "core/version.h" int EntitySpeciesData::get_id() const { return _id; } void EntitySpeciesData::set_id(const int value) { _id = value; } int EntitySpeciesData::get_type() const { return _type; } void EntitySpeciesData::set_type(const int value) { _type = value; } String EntitySpeciesData::get_text_description() const { return _text_description; } void EntitySpeciesData::set_text_description(const String &value) { _text_description = value; } //ModelData Ref EntitySpeciesData::get_model_data(const int index) const { ERR_FAIL_INDEX_V(index, _model_datas.size(), Ref()); return _model_datas.get(index); } void EntitySpeciesData::set_model_data(const int index, const Ref &model_data) { ERR_FAIL_INDEX(index, _model_datas.size()); _model_datas.set(index, model_data); } void EntitySpeciesData::add_model_data(const Ref &model_data) { _model_datas.push_back(model_data); } void EntitySpeciesData::remove_model_data(const int index) { ERR_FAIL_INDEX(index, _model_datas.size()); _model_datas.remove_at(index); } int EntitySpeciesData::get_model_data_count() const { return _model_datas.size(); } Vector EntitySpeciesData::get_model_datas() { VARIANT_ARRAY_GET(_model_datas); } void EntitySpeciesData::set_model_datas(const Vector &model_datas) { VARIANT_ARRAY_SET(model_datas, _model_datas, SpeciesModelData); } //Spells Ref EntitySpeciesData::get_spell(const int index) const { ERR_FAIL_INDEX_V(index, _spells.size(), Ref()); return _spells.get(index); } void EntitySpeciesData::set_spell(const int index, const Ref &spell) { ERR_FAIL_INDEX(index, _spells.size()); _spells.set(index, spell); } void EntitySpeciesData::add_spell(const Ref &spell) { _spells.push_back(spell); } void EntitySpeciesData::remove_spell(const int index) { ERR_FAIL_INDEX(index, _spells.size()); _spells.remove_at(index); } int EntitySpeciesData::get_spell_count() const { return _spells.size(); } Vector EntitySpeciesData::get_spells() { VARIANT_ARRAY_GET(_spells); } void EntitySpeciesData::set_spells(const Vector &spells) { VARIANT_ARRAY_SET(spells, _spells, Spell); } //Auras Ref EntitySpeciesData::get_aura(const int index) const { ERR_FAIL_INDEX_V(index, _auras.size(), Ref()); return _auras.get(index); } void EntitySpeciesData::set_aura(const int index, const Ref &aura) { ERR_FAIL_INDEX(index, _auras.size()); _auras.set(index, aura); } void EntitySpeciesData::add_aura(const Ref &aura) { _auras.push_back(aura); } void EntitySpeciesData::remove_aura(const int index) { ERR_FAIL_INDEX(index, _auras.size()); _auras.remove_at(index); } int EntitySpeciesData::get_aura_count() const { return _auras.size(); } Vector EntitySpeciesData::get_auras() { VARIANT_ARRAY_GET(_auras); } void EntitySpeciesData::set_auras(const Vector &auras) { _auras.clear(); for (int i = 0; i < auras.size(); i++) { Ref aura = Ref(auras[i]); _auras.push_back(aura); } } String EntitySpeciesData::generate_name(int seed) { if (has_method("_generate_name")) { return call("_generate_name", seed); } return ""; } EntitySpeciesData::EntitySpeciesData() { _id = 0; _type = 0; } EntitySpeciesData::~EntitySpeciesData() { _model_datas.clear(); _spells.clear(); _auras.clear(); } void EntitySpeciesData::_validate_property(PropertyInfo &property) const { if (property.name == "type") { property.hint_string = ESS::get_singleton()->entity_types_get(); } } void EntitySpeciesData::_bind_methods() { ////GDVIRTUAL_BIND("_generate_name", "seed"); ClassDB::bind_method(D_METHOD("generate_name"), &EntitySpeciesData::generate_name); ClassDB::bind_method(D_METHOD("get_id"), &EntitySpeciesData::get_id); ClassDB::bind_method(D_METHOD("set_id", "value"), &EntitySpeciesData::set_id); ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id"); ClassDB::bind_method(D_METHOD("get_type"), &EntitySpeciesData::get_type); ClassDB::bind_method(D_METHOD("set_type", "value"), &EntitySpeciesData::set_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, ""), "set_type", "get_type"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text_name"), "set_name", "get_name"); ClassDB::bind_method(D_METHOD("get_text_description"), &EntitySpeciesData::get_text_description); ClassDB::bind_method(D_METHOD("set_text_description", "value"), &EntitySpeciesData::set_text_description); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text_description"), "set_text_description", "get_text_description"); //ModelData ClassDB::bind_method(D_METHOD("get_model_data", "index"), &EntitySpeciesData::get_model_data); ClassDB::bind_method(D_METHOD("set_model_data", "index", "data"), &EntitySpeciesData::set_model_data); ClassDB::bind_method(D_METHOD("add_model_data", "model_data"), &EntitySpeciesData::add_model_data); ClassDB::bind_method(D_METHOD("remove_model_data", "index"), &EntitySpeciesData::remove_model_data); ClassDB::bind_method(D_METHOD("get_model_data_count"), &EntitySpeciesData::get_model_data_count); ClassDB::bind_method(D_METHOD("get_model_datas"), &EntitySpeciesData::get_model_datas); ClassDB::bind_method(D_METHOD("set_model_datas", "model_datas"), &EntitySpeciesData::set_model_datas); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "model_datas", PROPERTY_HINT_NONE, "17/17:SpeciesModelData", PROPERTY_USAGE_DEFAULT, "SpeciesModelData"), "set_model_datas", "get_model_datas"); //Spells ClassDB::bind_method(D_METHOD("get_spell", "index"), &EntitySpeciesData::get_spell); ClassDB::bind_method(D_METHOD("set_spell", "index", "data"), &EntitySpeciesData::set_spell); ClassDB::bind_method(D_METHOD("add_spell", "spell"), &EntitySpeciesData::add_spell); ClassDB::bind_method(D_METHOD("remove_spell", "index"), &EntitySpeciesData::remove_spell); ClassDB::bind_method(D_METHOD("get_spell_count"), &EntitySpeciesData::get_spell_count); ClassDB::bind_method(D_METHOD("get_spells"), &EntitySpeciesData::get_spells); ClassDB::bind_method(D_METHOD("set_spells", "spells"), &EntitySpeciesData::set_spells); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "spells", PROPERTY_HINT_NONE, "17/17:Spell", PROPERTY_USAGE_DEFAULT, "Spell"), "set_spells", "get_spells"); //Auras ClassDB::bind_method(D_METHOD("get_aura", "index"), &EntitySpeciesData::get_aura); ClassDB::bind_method(D_METHOD("set_aura", "index", "data"), &EntitySpeciesData::set_aura); ClassDB::bind_method(D_METHOD("add_aura", "aura"), &EntitySpeciesData::add_aura); ClassDB::bind_method(D_METHOD("remove_aura", "index"), &EntitySpeciesData::remove_aura); ClassDB::bind_method(D_METHOD("get_aura_count"), &EntitySpeciesData::get_aura_count); ClassDB::bind_method(D_METHOD("get_auras"), &EntitySpeciesData::get_auras); ClassDB::bind_method(D_METHOD("set_auras", "auras"), &EntitySpeciesData::set_auras); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "auras", PROPERTY_HINT_NONE, "17/17:Spell", PROPERTY_USAGE_DEFAULT, "Spell"), "set_auras", "get_auras"); } ================================================ FILE: data/species/entity_species_data.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef ENTITY_SPECIES_DATA_H #define ENTITY_SPECIES_DATA_H #include "core/version.h" #include "core/io/resource.h" #include "core/templates/vector.h" #include "core/string/ustring.h" #include "../../entity_enums.h" #include "species_model_data.h" class Spell; class EntitySpeciesData : public Resource { GDCLASS(EntitySpeciesData, Resource); public: int get_id() const; void set_id(const int value); int get_type() const; void set_type(const int value); String get_text_description() const; void set_text_description(const String &value); //ModelData Ref get_model_data(const int index) const; void set_model_data(const int index, const Ref &data); void add_model_data(const Ref &data); void remove_model_data(const int index); int get_model_data_count() const; Vector get_model_datas(); void set_model_datas(const Vector &datas); //Spells Ref get_spell(const int index) const; void set_spell(const int index, const Ref &spell); void add_spell(const Ref &spell); void remove_spell(const int index); int get_spell_count() const; Vector get_spells(); void set_spells(const Vector &spells); //Auras Ref get_aura(const int index) const; void set_aura(const int index, const Ref &aura); void add_aura(const Ref &aura); void remove_aura(const int index); int get_aura_count() const; Vector get_auras(); void set_auras(const Vector &auras); String generate_name(int seed); EntitySpeciesData(); ~EntitySpeciesData(); protected: void _validate_property(PropertyInfo &property) const; static void _bind_methods(); private: int _id; int _type; String _text_description; Vector > _model_datas; Vector > _spells; Vector > _auras; }; #endif ================================================ FILE: data/species/species_instance.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "species_instance.h" #include "core/version.h" #include "../../database/ess_resource_db.h" #include "../../singletons/ess.h" #include "entity_species_data.h" int SpeciesInstance::get_id() const { return _id; } void SpeciesInstance::set_id(const int value) { _id = value; } int SpeciesInstance::get_species_id() const { return _species_id; } void SpeciesInstance::set_species_id(int value) { _id = value; _species = ESS::get_singleton()->get_resource_db()->get_entity_species_data(_id); } StringName SpeciesInstance::get_species_path() const { return _path; } void SpeciesInstance::set_species_path(const StringName &value) { _path = value; _species = ESS::get_singleton()->get_resource_db()->get_entity_species_data_path(_path); } Ref SpeciesInstance::get_species() { return _species; } void SpeciesInstance::set_species(const Ref &value) { _species = value; if (_species.is_valid()) { _path = _species->get_path(); } else { _path = ""; } } int SpeciesInstance::get_skin_color_index() const { return _skin_color_index; } void SpeciesInstance::set_skin_color_index(const int value) { _skin_color_index = value; } int SpeciesInstance::get_hair_style_index() const { return _hair_style_index; } void SpeciesInstance::set_hair_style_index(const int value) { _hair_style_index = value; } int SpeciesInstance::get_hair_color_index() const { return _hair_color_index; } void SpeciesInstance::set_hair_color_index(const int value) { _hair_color_index = value; } int SpeciesInstance::get_head_index() const { return _head_index; } void SpeciesInstance::set_head_index(const int value) { _head_index = value; } Dictionary SpeciesInstance::to_dict() { return call("_to_dict"); } void SpeciesInstance::from_dict(const Dictionary &dict) { call("_from_dict", dict); } Dictionary SpeciesInstance::_to_dict() { Dictionary dict; dict["id"] = _id; dict["species_path"] = _path; dict["skin_color_index"] = _skin_color_index; dict["hair_style_index"] = _hair_style_index; dict["_hair_color_index"] = _hair_color_index; dict["head_index"] = _head_index; return dict; } void SpeciesInstance::_from_dict(const Dictionary &dict) { ERR_FAIL_COND(dict.is_empty()); _id = dict.get("id", 0); set_species_path(dict.get("species_path", "")); _skin_color_index = dict.get("skin_color_index", 0); _hair_style_index = dict.get("hair_style_index", 0); _hair_color_index = dict.get("hair_color_index", 0); _head_index = dict.get("head_index", 0); } SpeciesInstance::SpeciesInstance() { _id = 0; _species_id = 0; _skin_color_index = 0; _hair_style_index = 0; _hair_color_index = 0; _head_index = 0; } SpeciesInstance::~SpeciesInstance() { _species.unref(); } void SpeciesInstance::_bind_methods() { ClassDB::bind_method(D_METHOD("get_id"), &SpeciesInstance::get_id); ClassDB::bind_method(D_METHOD("set_id", "value"), &SpeciesInstance::set_id); ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id"); ClassDB::bind_method(D_METHOD("get_species_id"), &SpeciesInstance::get_species_id); ClassDB::bind_method(D_METHOD("set_species_id", "value"), &SpeciesInstance::set_species_id); ADD_PROPERTY(PropertyInfo(Variant::INT, "species_id"), "set_species_id", "get_species_id"); ClassDB::bind_method(D_METHOD("get_species"), &SpeciesInstance::get_species); ClassDB::bind_method(D_METHOD("set_species", "value"), &SpeciesInstance::set_species); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "species", PROPERTY_HINT_RESOURCE_TYPE, "EntitySpeciesData"), "set_species", "get_species"); ClassDB::bind_method(D_METHOD("get_skin_color_index"), &SpeciesInstance::get_skin_color_index); ClassDB::bind_method(D_METHOD("set_skin_color_index", "value"), &SpeciesInstance::set_skin_color_index); ADD_PROPERTY(PropertyInfo(Variant::INT, "skin_color_index"), "set_skin_color_index", "get_skin_color_index"); ClassDB::bind_method(D_METHOD("get_hair_style_index"), &SpeciesInstance::get_hair_style_index); ClassDB::bind_method(D_METHOD("set_hair_style_index", "value"), &SpeciesInstance::set_hair_style_index); ADD_PROPERTY(PropertyInfo(Variant::INT, "hair_style_index"), "set_hair_style_index", "get_hair_style_index"); ClassDB::bind_method(D_METHOD("get_hair_color_index"), &SpeciesInstance::get_hair_color_index); ClassDB::bind_method(D_METHOD("set_hair_color_index", "value"), &SpeciesInstance::set_hair_color_index); ADD_PROPERTY(PropertyInfo(Variant::INT, "hair_color_index"), "set_hair_color_index", "get_hair_color_index"); ClassDB::bind_method(D_METHOD("get_head_index"), &SpeciesInstance::get_head_index); ClassDB::bind_method(D_METHOD("set_head_index", "value"), &SpeciesInstance::set_head_index); ADD_PROPERTY(PropertyInfo(Variant::INT, "head_index"), "set_head_index", "get_head_index"); //Serialization //GDVIRTUAL_BIND("_from_dict", "dict"); //GDVIRTUAL_BIND("_to_dict"); ClassDB::bind_method(D_METHOD("from_dict", "dict"), &SpeciesInstance::from_dict); ClassDB::bind_method(D_METHOD("to_dict"), &SpeciesInstance::to_dict); ClassDB::bind_method(D_METHOD("_from_dict", "dict"), &SpeciesInstance::_from_dict); ClassDB::bind_method(D_METHOD("_to_dict"), &SpeciesInstance::_to_dict); } ================================================ FILE: data/species/species_instance.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef SPECIES_INSTANCE_H #define SPECIES_INSTANCE_H #include "core/version.h" #include "core/io/resource.h" #include "../items/model_visual_entry.h" class EntitySpeciesData; class SpeciesInstance : public Resource { GDCLASS(SpeciesInstance, Resource); public: int get_id() const; void set_id(const int value); int get_species_id() const; void set_species_id(const int value); StringName get_species_path() const; void set_species_path(const StringName &value); Ref get_species(); void set_species(const Ref &value); int get_skin_color_index() const; void set_skin_color_index(const int value); int get_hair_style_index() const; void set_hair_style_index(const int value); int get_hair_color_index() const; void set_hair_color_index(const int value); int get_head_index() const; void set_head_index(const int value); Dictionary to_dict(); void from_dict(const Dictionary &dict); Dictionary _to_dict(); void _from_dict(const Dictionary &dict); SpeciesInstance(); ~SpeciesInstance(); protected: static void _bind_methods(); private: int _id; StringName _path; int _species_id; Ref _species; int _skin_color_index; int _hair_style_index; int _hair_color_index; int _head_index; }; #endif ================================================ FILE: data/species/species_model_data.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "species_model_data.h" #include "core/version.h" #include "../../defines.h" #include "../../singletons/ess.h" #include "core/string/ustring.h" int SpeciesModelData::get_id() { return _id; } void SpeciesModelData::set_id(int value) { _id = value; } int SpeciesModelData::get_bone_structure() const { return _bone_structure; } void SpeciesModelData::set_bone_structure(const int value) { _bone_structure = value; } Ref SpeciesModelData::get_body() { return _body; } void SpeciesModelData::set_body(Ref value) { _body = value; } //Entries Ref SpeciesModelData::get_visual(const int index) const { ERR_FAIL_INDEX_V(index, _visuals.size(), Ref()); return _visuals.get(index); } void SpeciesModelData::set_visual(const int index, const Ref visual) { ERR_FAIL_INDEX(index, _visuals.size()); _visuals.set(index, visual); } void SpeciesModelData::add_visual(const Ref &visual) { _visuals.push_back(visual); } void SpeciesModelData::remove_visual(const int index) { ERR_FAIL_INDEX(index, _visuals.size()); _visuals.remove_at(index); } int SpeciesModelData::get_visual_count() const { return _visuals.size(); } Vector SpeciesModelData::get_visuals() { VARIANT_ARRAY_GET(_visuals); } void SpeciesModelData::set_visuals(const Vector &visuals) { VARIANT_ARRAY_SET(visuals, _visuals, ModelVisualEntry); } //Customizable Slots String SpeciesModelData::get_customizable_slots_string() const { return _customizable_slots_string; } void SpeciesModelData::set_customizable_slots_string(const String &value) { _customizable_slots_string = value; if (value == "") { _customizable_slots.resize(0); return; } _customizable_slots.resize(_customizable_slots_string.get_slice_count(",")); } Ref SpeciesModelData::get_customizable_slot_entry(const int slot_index, const int index) const { ERR_FAIL_INDEX_V(slot_index, _customizable_slots.size(), Ref()); ERR_FAIL_INDEX_V(index, _customizable_slots[slot_index].size(), Ref()); return _customizable_slots[slot_index].get(index); } void SpeciesModelData::set_customizable_slot_entry(const int slot_index, const int index, const Ref customizable_slot) { ERR_FAIL_INDEX(slot_index, _customizable_slots.size()); ERR_FAIL_INDEX(index, _customizable_slots[slot_index].size()); _customizable_slots.write[slot_index].set(index, customizable_slot); } void SpeciesModelData::add_customizable_slot_entry(const int slot_index, const Ref customizable_slot) { ERR_FAIL_INDEX(slot_index, _customizable_slots.size()); _customizable_slots.write[slot_index].push_back(customizable_slot); } void SpeciesModelData::remove_customizable_slot_entry(const int slot_index, const int index) { ERR_FAIL_INDEX(slot_index, _customizable_slots.size()); ERR_FAIL_INDEX(index, _customizable_slots.size()); _customizable_slots.write[slot_index].remove_at(index); } int SpeciesModelData::get_customizable_slot_count() const { return _customizable_slots.size(); } int SpeciesModelData::get_customizable_slot_entry_count(const int slot_index) const { ERR_FAIL_INDEX_V(slot_index, _customizable_slots.size(), 0); return _customizable_slots[slot_index].size(); } Vector SpeciesModelData::get_customizable_slot_entries(const int slot_index) const { Vector r; ERR_FAIL_INDEX_V(slot_index, _customizable_slots.size(), r); for (int i = 0; i < _customizable_slots[slot_index].size(); i++) { #if GODOT4 r.push_back(_customizable_slots[slot_index][i]); #else r.push_back(_customizable_slots[slot_index][i].get_ref_ptr()); #endif } return r; } void SpeciesModelData::set_customizable_slot_entries(const int slot_index, const Vector &customizable_slots) { ERR_FAIL_INDEX(slot_index, _customizable_slots.size()); _customizable_slots.write[slot_index].clear(); for (int i = 0; i < customizable_slots.size(); i++) { Ref e = Ref(customizable_slots[i]); _customizable_slots.write[slot_index].push_back(e); } } //Color Customizable Slots String SpeciesModelData::get_customizable_color_slots_string() const { return _customizable_color_slots_string; } void SpeciesModelData::set_customizable_color_slots_string(const String &value) { _customizable_color_slots_string = value; if (value == "") { _visuals.resize(0); return; } _customizable_color_slots.resize(_customizable_color_slots_string.get_slice_count(",")); } Color SpeciesModelData::get_color_customizable_slot_color(const int slot_index, const int index) const { ERR_FAIL_INDEX_V(slot_index, _customizable_color_slots.size(), Color()); ERR_FAIL_INDEX_V(index, _customizable_color_slots.size(), Color()); return _customizable_color_slots[slot_index].colors.get(index); } void SpeciesModelData::set_color_customizable_slot_color(const int slot_index, const int index, const Color color_customizable_slot) { ERR_FAIL_INDEX(slot_index, _customizable_color_slots.size()); ERR_FAIL_INDEX(index, _customizable_color_slots[slot_index].colors.size()); _customizable_color_slots.write[slot_index].colors.set(index, color_customizable_slot); } void SpeciesModelData::add_color_customizable_slot_color(const int slot_index, const Color color_customizable_slot) { ERR_FAIL_INDEX(slot_index, _customizable_color_slots.size()); _customizable_color_slots.write[slot_index].colors.push_back(color_customizable_slot); } void SpeciesModelData::remove_color_customizable_slot_color(const int slot_index, const int index) { ERR_FAIL_INDEX(slot_index, _customizable_color_slots.size()); ERR_FAIL_INDEX(index, _customizable_color_slots.size()); _customizable_color_slots.write[slot_index].colors.remove_at(index); } Vector SpeciesModelData::get_color_customizable_slot_colors(const int slot_index) const { ERR_FAIL_INDEX_V(slot_index, _customizable_color_slots.size(), Vector()); return _customizable_color_slots[slot_index].colors; } void SpeciesModelData::set_color_customizable_slot_colors(const int slot_index, const Vector &colors) { ERR_FAIL_INDEX(slot_index, _customizable_color_slots.size()); _customizable_color_slots.write[slot_index].colors = colors; } uint64_t SpeciesModelData::get_color_customizable_slot_bone_slot_mask(const int slot_index) const { ERR_FAIL_INDEX_V(slot_index, _customizable_color_slots.size(), 0); return _customizable_color_slots[slot_index].bone_slot_mask; } void SpeciesModelData::set_color_customizable_slot_bone_slot_mask(const int slot_index, const uint64_t value) { ERR_FAIL_INDEX(slot_index, _customizable_color_slots.size()); _customizable_color_slots.write[slot_index].bone_slot_mask = value; } int SpeciesModelData::get_color_customizable_slot_texture_layer(const int slot_index) const { ERR_FAIL_INDEX_V(slot_index, _customizable_color_slots.size(), 0); return _customizable_color_slots[slot_index].texture_layer; } void SpeciesModelData::set_color_customizable_slot_texture_layer(const int slot_index, const int value) { ERR_FAIL_INDEX(slot_index, _customizable_color_slots.size()); _customizable_color_slots.write[slot_index].texture_layer = value; } int SpeciesModelData::get_color_customizable_count() const { return _customizable_color_slots.size(); } int SpeciesModelData::get_color_customizable_slot_count(const int slot_index) const { ERR_FAIL_INDEX_V(slot_index, _customizable_color_slots.size(), 0); return _customizable_color_slots[slot_index].colors.size(); } SpeciesModelData::SpeciesModelData() { _id = 0; _bone_structure = 0; } SpeciesModelData::~SpeciesModelData() { _body.unref(); _visuals.clear(); for (int i = 0; i < _customizable_slots.size(); ++i) { _customizable_slots.write[i].clear(); } for (int i = 0; i < _customizable_color_slots.size(); ++i) { _customizable_color_slots.write[i].colors.clear(); } _customizable_slots.clear(); _customizable_color_slots.clear(); } bool SpeciesModelData::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; if (name.begins_with("customizable_slots")) { int index = name.get_slicec('/', 1).get_slicec('_', 0).to_int(); if (_customizable_slots.size() <= index) { _customizable_slots.resize(index + 1); } set_customizable_slot_entries(index, p_value); return true; } else if (name.begins_with("customizable_color_slots")) { int index = name.get_slicec('/', 1).get_slicec('_', 0).to_int(); if (_customizable_color_slots.size() <= index) { _customizable_color_slots.resize(index + 1); } String prop = name.get_slicec('/', 2); if (prop == "texture_layer") { _customizable_color_slots.write[index].texture_layer = p_value; return true; } else if (prop == "bone_slot_mask") { _customizable_color_slots.write[index].bone_slot_mask = p_value; return true; } else if (prop == "colors") { _customizable_color_slots.write[index].colors = p_value; return true; } return false; } return false; } bool SpeciesModelData::_get(const StringName &p_name, Variant &r_ret) const { String name = p_name; if (name.begins_with("customizable_slots")) { int index = name.get_slicec('/', 1).get_slicec('_', 0).to_int(); if (_customizable_slots.size() <= index) { return false; } r_ret = get_customizable_slot_entries(index); return true; } else if (name.begins_with("customizable_color_slots")) { int index = name.get_slicec('/', 1).get_slicec('_', 0).to_int(); if (_customizable_color_slots.size() <= index) { return false; } String prop = name.get_slicec('/', 2); if (prop == "texture_layer") { r_ret = _customizable_color_slots[index].texture_layer; return true; } else if (prop == "bone_slot_mask") { r_ret = _customizable_color_slots[index].bone_slot_mask; return true; } else if (prop == "colors") { r_ret = _customizable_color_slots[index].colors; return true; } return false; } return false; } void SpeciesModelData::_get_property_list(List *p_list) const { int count = _customizable_slots_string.get_slice_count(","); for (int i = 0; i < count; ++i) { p_list->push_back(PropertyInfo(Variant::ARRAY, "customizable_slots/" + itos(i) + "_" + _customizable_slots_string.get_slicec(',', i), PROPERTY_HINT_NONE, "17/17:ModelVisualEntry", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL, "ModelVisualEntry")); } count = _customizable_color_slots_string.get_slice_count(","); for (int i = 0; i < count; ++i) { p_list->push_back(PropertyInfo(Variant::INT, "customizable_color_slots/" + itos(i) + "_" + _customizable_color_slots_string.get_slicec(',', i) + "/texture_layer", PROPERTY_HINT_ENUM, ESS::get_singleton()->texture_layers_get(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED)); p_list->push_back(PropertyInfo(Variant::INT, "customizable_color_slots/" + itos(i) + "_" + _customizable_color_slots_string.get_slicec(',', i) + "/bone_slot_mask", PROPERTY_HINT_FLAGS, ESS::get_singleton()->skeletons_bones_index_get(_bone_structure), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::ARRAY, "customizable_color_slots/" + itos(i) + "_" + _customizable_color_slots_string.get_slicec(',', i) + "/colors", PROPERTY_HINT_NONE, "17/17:Color", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL, "Color")); } } void SpeciesModelData::_validate_property(PropertyInfo &property) const { String prop = property.name; if (prop == "bone_structure") { property.hint_string = ESS::get_singleton()->entity_types_get(); } } void SpeciesModelData::_bind_methods() { ClassDB::bind_method(D_METHOD("get_id"), &SpeciesModelData::get_id); ClassDB::bind_method(D_METHOD("set_id", "value"), &SpeciesModelData::set_id); ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id"); ClassDB::bind_method(D_METHOD("get_bone_structure"), &SpeciesModelData::get_bone_structure); ClassDB::bind_method(D_METHOD("set_bone_structure", "value"), &SpeciesModelData::set_bone_structure); ADD_PROPERTY(PropertyInfo(Variant::INT, "bone_structure", PROPERTY_HINT_ENUM, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_bone_structure", "get_bone_structure"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text_name"), "set_name", "get_name"); ClassDB::bind_method(D_METHOD("get_body"), &SpeciesModelData::get_body); ClassDB::bind_method(D_METHOD("set_body", "value"), &SpeciesModelData::set_body); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"), "set_body", "get_body"); //Entries ClassDB::bind_method(D_METHOD("get_visual", "index"), &SpeciesModelData::get_visual); ClassDB::bind_method(D_METHOD("set_visual", "index", "data"), &SpeciesModelData::set_visual); ClassDB::bind_method(D_METHOD("add_visual", "visual"), &SpeciesModelData::add_visual); ClassDB::bind_method(D_METHOD("remove_visual", "index"), &SpeciesModelData::remove_visual); ClassDB::bind_method(D_METHOD("get_visual_count"), &SpeciesModelData::get_visual_count); ClassDB::bind_method(D_METHOD("get_visuals"), &SpeciesModelData::get_visuals); ClassDB::bind_method(D_METHOD("set_visuals", "visuals"), &SpeciesModelData::set_visuals); //Customizable Slots ClassDB::bind_method(D_METHOD("get_customizable_slots_string"), &SpeciesModelData::get_customizable_slots_string); ClassDB::bind_method(D_METHOD("set_customizable_slots_string", "value"), &SpeciesModelData::set_customizable_slots_string); ADD_PROPERTY(PropertyInfo(Variant::STRING, "customizable_slots_string"), "set_customizable_slots_string", "get_customizable_slots_string"); ClassDB::bind_method(D_METHOD("get_customizable_slot_entry", "slot_index", "index"), &SpeciesModelData::get_customizable_slot_entry); ClassDB::bind_method(D_METHOD("set_customizable_slot_entry", "slot_index", "index", "data"), &SpeciesModelData::set_customizable_slot_entry); ClassDB::bind_method(D_METHOD("add_customizable_slot_entry", "slot_index", "customizable_slot"), &SpeciesModelData::add_customizable_slot_entry); ClassDB::bind_method(D_METHOD("remove_customizable_slot_entry", "slot_index", "index"), &SpeciesModelData::remove_customizable_slot_entry); ClassDB::bind_method(D_METHOD("get_customizable_slot_count"), &SpeciesModelData::get_customizable_slot_count); ClassDB::bind_method(D_METHOD("get_customizable_slot_entry_count", "slot_index"), &SpeciesModelData::get_customizable_slot_entry_count); ClassDB::bind_method(D_METHOD("get_customizable_slot_entries", "slot_index"), &SpeciesModelData::get_customizable_slot_entries); ClassDB::bind_method(D_METHOD("set_customizable_slot_entries", "slot_index", "customizable_slots"), &SpeciesModelData::set_customizable_slot_entries); //Color Slots ClassDB::bind_method(D_METHOD("get_customizable_color_slots_string"), &SpeciesModelData::get_customizable_color_slots_string); ClassDB::bind_method(D_METHOD("set_customizable_color_slots_string", "value"), &SpeciesModelData::set_customizable_color_slots_string); ADD_PROPERTY(PropertyInfo(Variant::STRING, "customizable_color_slots_string"), "set_customizable_color_slots_string", "get_customizable_color_slots_string"); ClassDB::bind_method(D_METHOD("get_color_customizable_slot_color", "slot_index", "index"), &SpeciesModelData::get_color_customizable_slot_color); ClassDB::bind_method(D_METHOD("set_color_customizable_slot_color", "slot_index", "index", "data"), &SpeciesModelData::set_color_customizable_slot_color); ClassDB::bind_method(D_METHOD("add_color_customizable_slot_color", "slot_index", "color_customizable_slot"), &SpeciesModelData::add_color_customizable_slot_color); ClassDB::bind_method(D_METHOD("remove_color_customizable_slot_color", "slot_index", "index"), &SpeciesModelData::remove_color_customizable_slot_color); ClassDB::bind_method(D_METHOD("get_color_customizable_slot_colors", "slot_index"), &SpeciesModelData::get_color_customizable_slot_colors); ClassDB::bind_method(D_METHOD("set_color_customizable_slot_colors", "slot_index", "colors"), &SpeciesModelData::set_color_customizable_slot_colors); ClassDB::bind_method(D_METHOD("get_color_customizable_slot_bone_slot_mask", "slot_index"), &SpeciesModelData::get_color_customizable_slot_bone_slot_mask); ClassDB::bind_method(D_METHOD("set_color_customizable_slot_bone_slot_mask", "slot_index", "value"), &SpeciesModelData::set_color_customizable_slot_bone_slot_mask); ClassDB::bind_method(D_METHOD("get_color_customizable_slot_texture_layer", "slot_index"), &SpeciesModelData::get_color_customizable_slot_texture_layer); ClassDB::bind_method(D_METHOD("set_color_customizable_slot_texture_layer", "slot_index", "value"), &SpeciesModelData::set_color_customizable_slot_texture_layer); ClassDB::bind_method(D_METHOD("get_color_customizable_count"), &SpeciesModelData::get_color_customizable_count); ClassDB::bind_method(D_METHOD("get_color_customizable_slot_count", "slot_index"), &SpeciesModelData::get_color_customizable_slot_count); } ================================================ FILE: data/species/species_model_data.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef SPECIES_MODEL_DATA_H #define SPECIES_MODEL_DATA_H #include "core/version.h" #include "core/io/resource.h" #include "core/templates/vector.h" #include "core/string/ustring.h" #include "core/math/color.h" #include "scene/resources/packed_scene.h" #include "../items/model_visual_entry.h" #include "../../entity_enums.h" class ModelVisual; class SpeciesModelData : public Resource { GDCLASS(SpeciesModelData, Resource); public: int get_id(); void set_id(int value); int get_bone_structure() const; void set_bone_structure(const int value); Ref get_body(); void set_body(Ref value); //Entries Ref get_visual(const int index) const; void set_visual(const int index, const Ref visual); void add_visual(const Ref &visual); void remove_visual(const int index); int get_visual_count() const; Vector get_visuals(); void set_visuals(const Vector &visuals); //Customizable Slots String get_customizable_slots_string() const; void set_customizable_slots_string(const String &value); Ref get_customizable_slot_entry(const int slot_index, const int index) const; void set_customizable_slot_entry(const int slot_index, const int index, const Ref customizable_slot); void add_customizable_slot_entry(const int slot_index, const Ref customizable_slot); void remove_customizable_slot_entry(const int slot_index, const int index); int get_customizable_slot_count() const; int get_customizable_slot_entry_count(const int slot_index) const; Vector get_customizable_slot_entries(const int slot_index) const; void set_customizable_slot_entries(const int slot_index, const Vector &customizable_slots); //Color Customizable Slots String get_customizable_color_slots_string() const; void set_customizable_color_slots_string(const String &value); Color get_color_customizable_slot_color(const int slot_index, const int index) const; void set_color_customizable_slot_color(const int slot_index, const int index, const Color color_customizable_slot); void add_color_customizable_slot_color(const int slot_index, const Color color_customizable_slot); void remove_color_customizable_slot_color(const int slot_index, const int index); Vector get_color_customizable_slot_colors(const int slot_index) const; void set_color_customizable_slot_colors(const int slot_index, const Vector &colors); uint64_t get_color_customizable_slot_bone_slot_mask(const int slot_index) const; void set_color_customizable_slot_bone_slot_mask(const int slot_index, const uint64_t value); int get_color_customizable_slot_texture_layer(const int slot_index) const; void set_color_customizable_slot_texture_layer(const int slot_index, const int value); int get_color_customizable_count() const; int get_color_customizable_slot_count(const int slot_index) const; SpeciesModelData(); ~SpeciesModelData(); protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List *p_list) const; void _validate_property(PropertyInfo &property) const; static void _bind_methods(); protected: struct ColorSlotData { int texture_layer; uint64_t bone_slot_mask; Vector colors; }; private: int _id; int _bone_structure; Ref _body; String _customizable_slots_string; String _customizable_color_slots_string; Vector > _visuals; Vector > > _customizable_slots; Vector _customizable_color_slots; }; #endif ================================================ FILE: data/spells/spell.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "spell.h" #include "../../entities/auras/aura_data.h" #include "../../entities/resources/entity_resource_cost_data.h" #include "../../entities/skills/entity_skill_data.h" #include "../items/craft_recipe.h" #include "../../entities/auras/aura_data.h" #include "../../entities/data/entity_data.h" #include "../../infos/aura_infos.h" #include "../auras/aura_group.h" #include "../../singletons/ess.h" #include "../../pipelines/spell_damage_info.h" #include "../../pipelines/spell_heal_info.h" #include "../../defines.h" int Spell::get_id() const { return _id; } void Spell::set_id(const int value) { _id = value; } int Spell::spell_type_get() const { return _spell_type; } void Spell::spell_type_set(int value) { _spell_type = value; } SpellEnums::SpellCategory Spell::get_spell_category() const { return _spell_category; } void Spell::set_spell_category(SpellEnums::SpellCategory value) { _spell_category = value; } bool Spell::get_hide_from_actionbar() const { return _hide_from_actionbar; } void Spell::set_hide_from_actionbar(const bool value) { _hide_from_actionbar = value; } float Spell::get_cooldown() const { return _cooldown; } void Spell::set_cooldown(const float value) { _cooldown = value; } SpellTargetType Spell::get_target_type() const { return _target_type; } void Spell::set_target_type(const SpellTargetType value) { _target_type = value; } TargetRelationType Spell::get_target_relation_type() const { return _target_relation_type; } void Spell::set_target_relation_type(const TargetRelationType value) { _target_relation_type = value; } int Spell::get_level() const { return _level; } void Spell::set_level(const int value) { _level = value; } int Spell::get_rank() const { return _rank; } void Spell::set_rank(const int value) { _rank = value; } bool Spell::get_scale_with_level() const { return _scale_with_level; } void Spell::set_scale_with_level(const bool value) { _scale_with_level = value; } Ref Spell::get_item_cost() { return _item_cost; } void Spell::set_item_cost(const Ref &value) { _item_cost = value; } Ref Spell::get_required_item() { return _required_item; } void Spell::set_required_item(const Ref &value) { _required_item = value; } Ref Spell::get_resource_cost() { return _resource_cost; } void Spell::set_resource_cost(const Ref &value) { _resource_cost = value; } Ref Spell::get_resource_give() { return _resource_give; } void Spell::set_resource_give(const Ref &value) { _resource_give = value; } bool Spell::get_global_cooldown_enabled() const { return _global_cooldown_enabled; } void Spell::set_global_cooldown_enabled(const bool value) { _global_cooldown_enabled = value; } bool Spell::get_is_local_spell() const { return _is_local_spell; } void Spell::set_is_local_spell(const bool value) { _is_local_spell = value; } Ref Spell::get_icon() { return _icon; } void Spell::set_icon(const Ref &value) { _icon = Ref(value); } String Spell::get_text_translation_key() const { return _text_translation_key; } void Spell::set_text_translation_key(const String &value) { _text_translation_key = value; } String Spell::get_text_description() const { return _text_description; } void Spell::set_text_description(const String &value) { _text_description = value; } Ref Spell::get_visual_spell_effects() { return _visual_spell_effects; } void Spell::set_visual_spell_effects(const Ref &value) { _visual_spell_effects = value; } Ref Spell::get_teaches_craft_recipe() { return _teaches_craft_recipe; } void Spell::set_teaches_craft_recipe(const Ref &value) { _teaches_craft_recipe = value; } //// Caster Aura Apply //// int Spell::spells_cast_on_caster_num_get() const { return _spells_cast_on_caster.size(); } void Spell::spells_cast_on_caster_num_set(const int value) { _spells_cast_on_caster.resize(value); } Ref Spell::spell_cast_on_caster_get(const int index) { ERR_FAIL_INDEX_V(index, _spells_cast_on_caster.size(), Ref()); return _spells_cast_on_caster[index]; } void Spell::spell_cast_on_caster_set(const int index, const Ref &spell) { ERR_FAIL_INDEX(index, _spells_cast_on_caster.size()); _spells_cast_on_caster.set(index, Ref(spell)); } Vector Spell::spells_cast_on_caster_get() { VARIANT_ARRAY_GET(_spells_cast_on_caster); } void Spell::spells_cast_on_caster_set(const Vector &spells) { VARIANT_ARRAY_SET(spells, _spells_cast_on_caster, Spell); } //// Target Aura Apply //// int Spell::spells_cast_on_target_num_get() const { return _spells_cast_on_target.size(); } void Spell::spells_cast_on_target_num_set(const int value) { _spells_cast_on_target.resize(value); } Ref Spell::spell_cast_on_target_get(const int index) { ERR_FAIL_INDEX_V(index, _spells_cast_on_target.size(), Ref()); return _spells_cast_on_target[index]; } void Spell::spell_cast_on_target_set(const int index, const Ref &spell) { ERR_FAIL_INDEX(index, _spells_cast_on_target.size()); _spells_cast_on_target.set(index, Ref(spell)); } Vector Spell::spells_cast_on_target_get() { VARIANT_ARRAY_GET(_spells_cast_on_target); } void Spell::spells_cast_on_target_set(const Vector &spells) { VARIANT_ARRAY_SET(spells, _spells_cast_on_target, Spell); } //// Apply Auras On Learn //// int Spell::on_learn_cast_spells_num_get() const { return _on_learn_cast_spells.size(); } void Spell::on_learn_cast_spells_num_set(const int value) { _on_learn_cast_spells.resize(value); } Ref Spell::spell_cast_on_learn_get(int index) { ERR_FAIL_INDEX_V(index, _on_learn_cast_spells.size(), Ref()); return _on_learn_cast_spells[index]; } void Spell::spell_cast_on_learn_set(const int index, const Ref &spell) { ERR_FAIL_INDEX(index, _on_learn_cast_spells.size()); _on_learn_cast_spells.set(index, Ref(spell)); } Vector Spell::spells_cast_on_learn_get() { VARIANT_ARRAY_GET(_on_learn_cast_spells); } void Spell::spells_cast_on_learn_set(const Vector &spells) { VARIANT_ARRAY_SET(spells, _on_learn_cast_spells, Spell); } //// Range //// bool Spell::range_get_enabled() const { return _range_enabled; } void Spell::range_set_enabled(const bool value) { _range_enabled = value; } float Spell::range_get() const { return _range; } void Spell::range_set(const float value) { _range = value; } bool Spell::cast_time_get_enabled() const { return _cast_time_enabled; } void Spell::cast_time_set_enabled(const bool value) { _cast_time_enabled = value; } float Spell::cast_time_get() const { return _cast_time; } void Spell::cast_time_set(const float value) { _cast_time = value; } bool Spell::projectile_get_use_time() const { return _projectile_use_time; } void Spell::projectile_set_use_time(const bool value) { _projectile_use_time = value; } float Spell::projectile_get_time() const { return _projectile_time; } void Spell::projectile_set_time(const float value) { _projectile_time = value; } bool Spell::projectile_get_use_speed() const { return _projectile_use_speed; } void Spell::projectile_set_use_speed(const bool value) { _projectile_use_speed = value; } float Spell::projectile_get_speed() const { return _projectile_speed; } void Spell::projectile_set_speed(const float value) { _projectile_speed = value; } Ref Spell::projectile_get_scene() const { return _projectile_scene; } void Spell::projectile_set_scene(const Ref &value) { _projectile_scene = value; } bool Spell::damage_get_enabled() const { return _damage_enabled; } void Spell::damage_set_enabled(const bool value) { _damage_enabled = value; } int Spell::damage_get_type() const { return _damage_type; } void Spell::damage_set_type(const int value) { _damage_type = value; } int Spell::damage_get_min() const { return _damage_min; } void Spell::damage_set_min(const int value) { _damage_min = value; } int Spell::damage_get_max() const { return _damage_max; } void Spell::damage_set_max(const int value) { _damage_max = value; } int Spell::damage_get_scale_stat() const { return _damage_scale_stat; } void Spell::damage_set_scale_stat(const int value) { _damage_scale_stat = value; } float Spell::damage_get_scale_coeff() const { return _damage_scale_coeff; } void Spell::damage_set_scale_coeff(const float value) { _damage_scale_coeff = value; } bool Spell::heal_get_enabled() const { return _heal_enabled; } void Spell::heal_set_enabled(const bool value) { _heal_enabled = value; } int Spell::heal_get_min() const { return _heal_min; } void Spell::heal_set_min(const int value) { _heal_min = value; } int Spell::heal_get_max() const { return _heal_max; } void Spell::heal_set_max(const int value) { _heal_max = value; } int Spell::heal_get_scale_stat() const { return _heal_scale_stat; } void Spell::heal_set_scale_stat(const int value) { _heal_scale_stat = value; } float Spell::heal_get_scale_coeff() const { return _heal_scale_coeff; } void Spell::heal_set_scale_coeff(const float value) { _heal_scale_coeff = value; } bool Spell::dispell_get_enabled() const { return _dispell_enabled; } void Spell::dispell_set_enabled(const bool value) { _dispell_enabled = value; } int Spell::dispell_get_count_min() const { return _dispell_count_min; } void Spell::dispell_set_count_min(const int value) { _dispell_count_min = value; } int Spell::dispell_get_count_max() const { return _dispell_count_max; } void Spell::dispell_set_count_max(const int value) { _dispell_count_max = value; } int Spell::dispell_get_aura_types() const { return _dispell_aura_types; } void Spell::dispell_set_aura_types(const int value) { _dispell_aura_types = value; } bool Spell::get_needs_target() const { return _needs_target; } void Spell::set_needs_target(const bool value) { _needs_target = value; } bool Spell::get_can_move_while_casting() const { return _can_move_while_casting; } void Spell::set_can_move_while_casting(const bool value) { _can_move_while_casting = value; } bool Spell::get_interrupt_enabled() const { return _interrupt_enabled; } void Spell::set_interrupt_enabled(const bool value) { _interrupt_enabled = value; } float Spell::get_interrupt_time() const { return _interrupt_time; } void Spell::set_interrupt_time(const float value) { _interrupt_time = value; } bool Spell::get_is_aoe() const { return _is_aoe; } void Spell::set_is_aoe(const bool value) { _is_aoe = value; } SpellAOETargetType Spell::get_aoe_target_type() const { return _aoe_targetType; } void Spell::set_aoe_target_type(const SpellAOETargetType value) { _aoe_targetType = value; } SpellEnums::ColliderType Spell::get_aoe_collider_type() const { return _aoe_colliderType; } void Spell::set_aoe_collider_type(const SpellEnums::ColliderType value) { _aoe_colliderType = value; } float Spell::get_aoe_radius() const { return _aoe_radius; } void Spell::set_aoe_radius(float value) { _aoe_radius = value; } Vector3 Spell::get_aoe_box_extents() const { return _aoe_box_extents; } void Spell::set_aoe_box_extents(Vector3 value) { _aoe_box_extents = value; } int Spell::get_spell_cooldown_mainpulation_data_count() const { return _spell_cooldown_mainpulation_data_count; } void Spell::set_spell_cooldown_mainpulation_data_count(int value) { _spell_cooldown_mainpulation_data_count = value; } int Spell::get_training_cost() const { return _training_cost; } void Spell::set_training_cost(const int value) { _training_cost = value; } Ref Spell::get_training_required_spell() { return _training_required_spell; } void Spell::set_training_required_spell(const Ref &spell) { _training_required_spell = spell; } Ref Spell::get_training_required_skill() { return _training_required_skill; } void Spell::set_training_required_skill(const Ref &skill) { _training_required_skill = skill; } int Spell::get_training_required_skill_level() const { return _training_required_skill_level; } void Spell::set_training_required_skill_level(const int value) { _training_required_skill_level = value; } // Aura bool Spell::aura_get_permanent() const { return _aura_permanent; } void Spell::aura_set_permanent(const bool value) { _aura_permanent = value; } float Spell::aura_get_time() const { return _aura_time; } void Spell::aura_set_time(const float value) { _aura_time = value; } float Spell::aura_get_tick() const { return _aura_tick; } void Spell::aura_set_tick(const float value) { _aura_tick = value; } Ref Spell::aura_get_aura_group() { return _aura_group; } void Spell::aura_set_aura_group(const Ref &value) { _aura_group = value; } bool Spell::aura_get_is_debuff() const { return _aura_is_debuff; } void Spell::aura_set_is_debuff(const bool value) { _aura_is_debuff = value; } SpellEnums::AuraType Spell::aura_get_aura_type() const { return _aura_type; } void Spell::aura_set_aura_type(SpellEnums::AuraType value) { _aura_type = value; } bool Spell::aura_get_scale_with_level() const { return _aura_scale_with_level; } void Spell::aura_set_scale_with_level(const bool value) { _aura_scale_with_level = value; } String Spell::aura_get_text_translation_key() const { return _aura_text_translation_key; } void Spell::aura_set_text_translation_key(const String &value) { _aura_text_translation_key = value; } String Spell::aura_get_text_description() const { return _aura_text_description; } void Spell::aura_set_text_description(const String description) { _aura_text_description = description; } bool Spell::aura_get_hide() const { return _aura_hide; } void Spell::aura_set_hide(const bool value) { _aura_hide = value; } Ref Spell::aura_get_visual_spell_effects() { return _aura_visual_spell_effects; } void Spell::aura_set_visual_spell_effects(const Ref &value) { _aura_visual_spell_effects = value; } int Spell::aura_get_ability_scale_data_id() const { return _aura_ability_scale_data_id; } void Spell::aura_set_ability_scale_data_id(const int value) { _aura_ability_scale_data_id = value; } float Spell::aura_damage_get_scale_for_level(const int level) const { //return this->getDamageLevelScaling()->Evaluate((float)(level)); return 1; } float Spell::aura_heal_get_scale_for_level(const int level) const { //return this->getHealLevelScaling()->Evaluate((float)(level)); return 1; } float Spell::aura_absorb_get_scale_for_level(const int level) const { //return this->getAbsorbLevelScaling()->Evaluate((float)(level)); return 1; } bool Spell::aura_diminishing_return_enabled_get() const { return _aura_diminishing_return_enabled; } void Spell::aura_diminishing_return_enabled_set(const bool value) { _aura_diminishing_return_enabled = value; } int Spell::aura_diminishing_return_category_get() const { return _aura_diminishing_return_category; } void Spell::aura_diminishing_return_category_set(const int value) { _aura_diminishing_return_category = value; } Ref Spell::aura_get_teaches_spell() { return _aura_teaches_spell; } void Spell::aura_set_teaches_spell(const Ref &spell) { _aura_teaches_spell = spell; } /* void Spell::SetScalingData(AbilityScalingData *scalingData) { scalingData->getDamageCurve(); scalingData->getAbsorbCurve(); scalingData->getHealingCurve(); }*/ /* void Spell::OnAuraAbilityScalingDataLoaded(AbilityScalingDataLoaderHelper *h) { this->SetScalingData(h->getData()); } */ //Damage bool Spell::aura_damage_get_enabled() const { return _aura_damage_enabled; } void Spell::aura_damage_set_enabled(const bool value) { _aura_damage_enabled = value; } int Spell::aura_damage_get_type() const { return _aura_damage_type; } void Spell::aura_damage_set_type(const int value) { _aura_damage_type = value; } int Spell::aura_damage_get_min() const { return _aura_damage_min; } void Spell::aura_damage_set_min(const int value) { _aura_damage_min = value; } int Spell::aura_damage_get_max() const { return _aura_damage_max; } void Spell::aura_damage_set_max(const int value) { _aura_damage_max = value; } bool Spell::aura_damage_get_can_crit() const { return _aura_damage_can_crit; } void Spell::aura_damage_set_can_crit(const bool value) { _aura_damage_can_crit = value; } void Spell::aura_damage_set(const int min, const int max, const bool can_crit) { aura_damage_set_enabled(true); aura_damage_set_min(min); aura_damage_set_max(max); aura_damage_set_can_crit(can_crit); } //Absorb bool Spell::aura_absorb_get_enabled() const { return _aura_absorb_enabled; } void Spell::aura_absorb_set_enabled(const bool value) { _aura_absorb_enabled = value; } int Spell::aura_absorb_damage_get_type() const { return _aura_absorb_damage_type; } void Spell::aura_absorb_damage_set_type(const int value) { _aura_absorb_damage_type = value; } int Spell::aura_absorb_get_min() const { return _aura_absorb_min; } void Spell::aura_absorb_set_min(const int value) { _aura_absorb_min = value; } int Spell::aura_absorb_get_max() const { return _aura_absorb_max; } void Spell::aura_absorb_set_max(const int value) { _aura_absorb_max = value; } //Heal bool Spell::aura_heal_get_enabled() const { return _aura_heal_enabled; } void Spell::aura_heal_set_enabled(const bool value) { _aura_heal_enabled = value; } int Spell::aura_heal_get_min() const { return _aura_heal_min; } void Spell::aura_heal_set_min(const int value) { _aura_heal_min = value; } int Spell::aura_heal_get_max() const { return _aura_heal_max; } void Spell::aura_heal_set_max(const int value) { _aura_heal_max = value; } bool Spell::aura_heal_get_can_crit() const { return _aura_heal_can_crit; } void Spell::aura_heal_set_can_crit(const bool value) { _aura_heal_can_crit = value; } void Spell::aura_heal_set(const int min, const int max, const bool can_crit) { aura_heal_set_enabled(true); aura_heal_set_min(min); aura_heal_set_max(max); aura_heal_set_can_crit(can_crit); } //Dispell bool Spell::aura_dispell_get_enabled() const { return _aura_dispell_enabled; } void Spell::aura_dispell_set_enabled(const bool value) { _aura_dispell_enabled = value; } int Spell::aura_dispell_get_count_min() const { return _aura_dispell_count_min; } void Spell::aura_dispell_set_count_min(const int value) { _aura_dispell_count_min = value; } int Spell::aura_dispell_get_count_max() const { return _aura_dispell_count_max; } void Spell::aura_dispell_set_count_max(const int value) { _aura_dispell_count_max = value; } int Spell::aura_dispell_get_aura_types() const { return _aura_dispell_aura_types; } void Spell::aura_dispell_set_aura_types(const int value) { _aura_dispell_aura_types = value; } Ref Spell::aura_get_resource_cost() { return _aura_resource_cost; } void Spell::aura_set_resource_cost(const Ref &value) { _aura_resource_cost = value; } Ref Spell::aura_get_resource_give() { return _aura_resource_give; } void Spell::aura_set_resource_give(const Ref &value) { _aura_resource_give = value; } ////// Triggers /////// int Spell::aura_trigger_get_count() const { return _aura_trigger_count; } void Spell::aura_trigger_set_count(const int count) { ERR_FAIL_COND(count < 0 || count > MAX_TRIGGER_DATA); _aura_trigger_count = count; } SpellEnums::TriggerNotificationType Spell::aura_trigger_get_notification_type(const int index) const { ERR_FAIL_INDEX_V(index, _aura_trigger_count, SpellEnums::TRIGGER_NOTIFICATION_TYPE_AURA); return _aura_trigger_datas[index].notification_type; } void Spell::aura_trigger_set_notification_type(const int index, const SpellEnums::TriggerNotificationType value) { ERR_FAIL_COND(index < 0 || index > _aura_trigger_count); _aura_trigger_datas[index].notification_type = value; } int Spell::aura_trigger_get_notification_data(const int index) const { ERR_FAIL_INDEX_V(index, _aura_trigger_count, 0); return _aura_trigger_datas[index].notification_data; } void Spell::aura_trigger_set_notification_data(const int index, const int value) { ERR_FAIL_COND(index < 0 || index > _aura_trigger_count); _aura_trigger_datas[index].notification_data = value; } SpellEnums::TriggerType Spell::aura_trigger_get_trigger_type(const int index) const { ERR_FAIL_INDEX_V(index, _aura_trigger_count, SpellEnums::TRIGGER_TYPE_NONE); return _aura_trigger_datas[index].trigger_type; } void Spell::aura_trigger_set_trigger_type(const int index, const SpellEnums::TriggerType value) { ERR_FAIL_COND(index < 0 || index > _aura_trigger_count); _aura_trigger_datas[index].trigger_type = value; } float Spell::aura_trigger_get_trigger_type_data(const int index) const { ERR_FAIL_INDEX_V(index, _aura_trigger_count, 0); return _aura_trigger_datas[index].trigger_type_data; } void Spell::aura_trigger_set_trigger_type_data(const int index, const float value) { ERR_FAIL_COND(index < 0 || index > _aura_trigger_count); _aura_trigger_datas[index].trigger_type_data = value; } Ref Spell::aura_trigger_get_spell(const int index) const { ERR_FAIL_INDEX_V(index, _aura_trigger_count, Ref()); return _aura_trigger_datas[index].spell; } void Spell::aura_trigger_set_spell(const int index, const Ref &value) { ERR_FAIL_COND(index < 0 || index > _aura_trigger_count); _aura_trigger_datas[index].spell = value; } //// Talent //// Ref Spell::aura_get_talent_required_talent() const { return _aura_talent_required_talent; } void Spell::aura_set_talent_required_talent(const Ref rank) { _aura_talent_required_talent = rank; } Ref Spell::aura_get_talent_required_spell() const { return _aura_talent_required_talent; } void Spell::aura_set_talent_required_spell(const Ref spell) { _aura_talent_required_spell = spell; } ////// Aura Stat Attributes ////// int Spell::aura_stat_attribute_get_count() const { return _aura_stat_attribute_count; } void Spell::aura_stat_attribute_set_count(int count) { ERR_FAIL_COND(count < 0 || count > MAX_AURA_STATS); _aura_stat_attribute_count = count; } int Spell::aura_stat_attribute_get_stat(int index) const { ERR_FAIL_INDEX_V(index, MAX_AURA_STATS, 0); return _aura_stat_attributes[index].stat; } void Spell::aura_stat_attribute_set_stat(int index, const int value) { ERR_FAIL_INDEX(index, MAX_AURA_STATS); _aura_stat_attributes[index].stat = value; } float Spell::aura_stat_attribute_get_base_mod(int index) const { ERR_FAIL_INDEX_V(index, MAX_AURA_STATS, 0); return _aura_stat_attributes[index].base_mod; } void Spell::aura_stat_attribute_set_base_mod(int index, float value) { ERR_FAIL_INDEX(index, MAX_AURA_STATS); _aura_stat_attributes[index].base_mod = value; } float Spell::aura_stat_attribute_get_bonus_mod(int index) const { ERR_FAIL_INDEX_V(index, MAX_AURA_STATS, 0); return _aura_stat_attributes[index].bonus_mod; } void Spell::aura_stat_attribute_set_bonus_mod(int index, float value) { ERR_FAIL_INDEX(index, MAX_AURA_STATS); _aura_stat_attributes[index].bonus_mod = value; } float Spell::aura_stat_attribute_get_percent_mod(int index) const { ERR_FAIL_INDEX_V(index, MAX_AURA_STATS, 0); return _aura_stat_attributes[index].percent_mod; } void Spell::aura_stat_attribute_set_percent_mod(int index, float value) { ERR_FAIL_INDEX(index, MAX_AURA_STATS); _aura_stat_attributes[index].percent_mod = value; } //// Spell System //// void Spell::cast_starts_simple(Entity *caster, float spell_scale) { ERR_FAIL_COND(!caster || !INSTANCE_VALIDATE(caster)); Ref info = Ref(memnew(SpellCastInfo())); info->caster_set(caster); info->target_set(caster->gets_target()); info->has_cast_time_set(cast_time_get_enabled()); info->cast_time_set(cast_time_get()); info->spell_scale_set(spell_scale); info->set_spell(Ref(this)); cast_starts(info); } void Spell::cast_interrupts_simple(Entity *caster) { ERR_FAIL_COND(!caster || !INSTANCE_VALIDATE(caster)); Ref info(memnew(SpellCastInfo())); info->caster_set(caster); info->set_spell(Ref(this)); cast_interrupts(info); } void Spell::cast_starts_triggered_simple(Entity *caster) { ERR_FAIL_COND(!caster || !INSTANCE_VALIDATE(caster)); Ref info(memnew(SpellCastInfo())); info->caster_set(caster); info->set_spell(Ref(this)); cast_starts_triggered(info); } void Spell::aura_sapply_simple(Entity *caster, Entity *target, float spell_scale) { ERR_FAIL_COND(caster == NULL || target == NULL); Ref info(memnew(AuraApplyInfo(caster, target, spell_scale, this))); aura_sapply(info); } //Script methods void Spell::cast_starts(Ref info) { ERR_FAIL_COND(!info.is_valid()); //Auto self cast. Note: Remove needs_target, and skip this if spell should only target enemies. if (info->target_get() == NULL) { info->target_set(info->caster_get()); } if (has_method("_cast_starts")) { call("_cast_starts", info); } } void Spell::cast_starts_triggered(Ref info) { ERR_FAIL_COND(!info.is_valid()); if (has_method("_cast_starts_triggered")) { call("_cast_starts_triggered", info); } } void Spell::cast_interrupts(Ref info) { ERR_FAIL_COND(!info.is_valid()); if (has_method("_cast_interrupts")) { call("_cast_interrupts", info); } } void Spell::cast_finishs(Ref info) { ERR_FAIL_COND(!info.is_valid()); if (has_method("_cast_finishs")) { call("_cast_finishs", info); } } void Spell::aura_sapply(Ref info) { ERR_FAIL_COND(!info.is_valid()); //always exists call("_aura_sapply", info); } void Spell::aura_sdeapply(Ref info) { ERR_FAIL_COND(!info.is_valid()); //always exists call("_aura_sdeapply", info); } void Spell::aura_sadd(Ref aura) { ERR_FAIL_COND(!aura.is_valid()); //always exists call("_aura_sadd", aura); } void Spell::aura_sremove(Ref aura) { ERR_FAIL_COND(!aura.is_valid()); //always exists call("_aura_sremove", aura); } void Spell::aura_removes_expired(Ref aura) { ERR_FAIL_COND(!aura.is_valid()); //always exists call("_aura_removes_expired", aura); } void Spell::aura_removes_dispell(Ref aura) { ERR_FAIL_COND(!aura.is_valid()); //always exists call("_aura_removes_dispell", aura); } void Spell::aura_supdate(Ref aura, float delta) { ERR_FAIL_COND(!aura.is_valid()); //always exists call("_aura_supdate", aura, delta); } //eventhandlers void Spell::son_cast_player_moved(Ref info) { ERR_FAIL_COND(!info.is_valid()); if (has_method("_son_cast_player_moved")) { call("_son_cast_player_moved", info); } } void Spell::son_cast_damage_received(Ref info) { ERR_FAIL_COND(!info.is_valid()); if (has_method("_son_cast_damage_received")) { call("_son_cast_damage_received", info); } } void Spell::son_spell_hit(Ref info) { ERR_FAIL_COND(!info.is_valid()); if (has_method("_son_spell_hit")) { call("_son_spell_hit", info); } } void Spell::son_physics_process(Ref info, float delta) { ERR_FAIL_COND(!info.is_valid()); if (has_method("_son_physics_process")) { call("_son_physics_process", info, delta); } } void Spell::notification_scast(int what, Ref info) { ERR_FAIL_COND(!info.is_valid()); if (has_method("_notification_scast")) { call("_notification_scast", what, info); } } void Spell::notification_ccast(int what, Ref info) { ERR_FAIL_COND(!info.is_valid()); if (has_method("_notification_ccast")) { call("_notification_ccast", what, info); } } void Spell::notification_saura(int what, Ref data) { ERR_FAIL_COND(!data.is_valid()); if (has_method("_notification_saura")) call("_notification_saura", what, data); } void Spell::notification_sheal(int what, Ref aura, Ref data) { ERR_FAIL_COND(!aura.is_valid()); ERR_FAIL_COND(!data.is_valid()); if (has_method("_notification_sheal")) call("_notification_sheal", what, aura, data); } void Spell::notification_aura_scast(int what, Ref aura, Ref info) { ERR_FAIL_COND(!aura.is_valid()); ERR_FAIL_COND(!info.is_valid()); if (has_method("_notification_aura_scast")) call("_notification_aura_scast", what, aura, info); } void Spell::notification_sdamage(int what, Ref aura, Ref data) { ERR_FAIL_COND(!aura.is_valid()); ERR_FAIL_COND(!data.is_valid()); if (has_method("_notification_sdamage")) call("_notification_sdamage", what, aura, data); } void Spell::son_remove_expired(Ref aura) { ERR_FAIL_COND(!aura.is_valid()); if (has_method("_son_remove_expired")) call("_son_remove_expired", aura); } void Spell::son_remove(Ref aura) { ERR_FAIL_COND(!aura.is_valid()); if (has_method("_son_remove")) call("_son_remove", aura); } void Spell::son_remove_dispell(Ref aura) { ERR_FAIL_COND(!aura.is_valid()); if (has_method("_son_remove_dispell")) call("_son_remove_dispell", aura); } void Spell::notification_sdeath(Ref data) { if (has_method("_notification_sdeath")) call("_notification_sdeath", data); } void Spell::notification_scooldown_added(Ref data, int id, float value) { if (has_method("_notification_scooldown_added")) call("_notification_scooldown_added", data, id, value); } void Spell::notification_scooldown_removed(Ref data, int id, float value) { if (has_method("_notification_scooldown_removed")) call("_notification_scooldown_removed", data, id, value); } void Spell::notification_scategory_cooldown_added(Ref data, int id, float value) { if (has_method("_notification_scategory_cooldown_added")) call("_notification_scategory_cooldown_added", data, id, value); } void Spell::notification_scategory_cooldown_removed(Ref data, int id, float value) { if (has_method("_notification_scategory_cooldown_removed")) call("_notification_scategory_cooldown_removed", data, id, value); } void Spell::notification_sgcd_started(Ref data, float gcd) { ERR_FAIL_COND(!data.is_valid()); if (has_method("_notification_sgcd_started")) call("_notification_sgcd_started", data, gcd); } void Spell::notification_sgcd_finished(Ref data) { ERR_FAIL_COND(!data.is_valid()); if (has_method("_notification_sgcd_finished")) call("_notification_sgcd_finished", data); } void Spell::son_physics_process_aura(Ref data) { ERR_FAIL_COND(!data.is_valid()); if (has_method("_son_physics_process_aura")) call("_son_physics_process_aura", data); } void Spell::notification_sxp_gained(Ref data, int value) { ERR_FAIL_COND(!data.is_valid()); if (has_method("_notification_sxp_gained")) call("_notification_sxp_gained", data, value); } void Spell::notification_slevel_up(Ref data, int value) { ERR_FAIL_COND(!data.is_valid()); if (has_method("_notification_slevel_up")) call("_notification_slevel_up", data, value); } void Spell::notification_sentity_resource_added(Ref data, Ref resource) { ERR_FAIL_COND(!data.is_valid()); ERR_FAIL_COND(!resource.is_valid()); if (has_method("_notification_sentity_resource_added")) call("_notification_sentity_resource_added", data, resource); } void Spell::notification_sentity_resource_removed(Ref data, Ref resource) { ERR_FAIL_COND(!data.is_valid()); ERR_FAIL_COND(!resource.is_valid()); if (has_method("_notification_sentity_resource_removed")) call("_notification_sentity_resource_removed", data, resource); } void Spell::notification_caura(int what, Ref data) { ERR_FAIL_COND(!data.is_valid()); if (has_method("_notification_caura")) call("_notification_caura", what, data); } void Spell::notification_cheal(int what, Ref aura, Ref data) { ERR_FAIL_COND(!aura.is_valid()); ERR_FAIL_COND(!data.is_valid()); if (has_method("_notification_cheal")) call("_notification_cheal", what, aura, data); } void Spell::notification_aura_ccast(int what, Ref aura, Ref info) { ERR_FAIL_COND(!aura.is_valid()); ERR_FAIL_COND(!info.is_valid()); if (has_method("_notification_aura_ccast")) call("_notification_aura_ccast", what, aura, info); } void Spell::notification_cdamage(int what, Ref aura, Ref data) { ERR_FAIL_COND(!aura.is_valid()); ERR_FAIL_COND(!data.is_valid()); if (has_method("_notification_cdamage")) call("_notification_cdamage", what, aura, data); } void Spell::notification_cdeath(Ref data) { if (has_method("_notification_cdeath")) call("_notification_cdeath", data); } void Spell::notification_ccooldown_added(Ref data, int id, float value) { if (has_method("_notification_ccooldown_added")) call("_notification_ccooldown_added", data, id, value); } void Spell::notification_ccooldown_removed(Ref data, int id, float value) { if (has_method("_notification_ccooldown_removed")) call("_notification_ccooldown_removed", data, id, value); } void Spell::notification_ccategory_cooldown_added(Ref data, int id, float value) { if (has_method("_notification_ccategory_cooldown_added")) call("_notification_ccategory_cooldown_added", data, id, value); } void Spell::notification_ccategory_cooldown_removed(Ref data, int id, float value) { if (has_method("_notification_ccategory_cooldown_removed")) call("_notification_ccategory_cooldown_removed", data, id, value); } void Spell::notification_cgcd_started(Ref data, float gcd) { ERR_FAIL_COND(!data.is_valid()); if (has_method("_notification_cgcd_started")) call("_notification_cgcd_started", data, gcd); } void Spell::notification_cgcd_finished(Ref data) { ERR_FAIL_COND(!data.is_valid()); if (has_method("_notification_cgcd_finished")) call("_notification_cgcd_finished", data); } void Spell::notification_cxp_gained(Ref data, int value) { ERR_FAIL_COND(!data.is_valid()); if (has_method("_notification_cxp_gained")) call("_notification_cxp_gained", data, value); } void Spell::notification_clevel_up(Ref data, int value) { ERR_FAIL_COND(!data.is_valid()); if (has_method("_notification_clevel_up")) call("_notification_clevel_up", data, value); } void Spell::notification_centity_resource_added(Ref data, Ref resource) { ERR_FAIL_COND(!data.is_valid()); ERR_FAIL_COND(!resource.is_valid()); if (has_method("_notification_centity_resource_added")) call("_notification_centity_resource_added", data, resource); } void Spell::notification_centity_resource_removed(Ref data, Ref resource) { ERR_FAIL_COND(!data.is_valid()); ERR_FAIL_COND(!resource.is_valid()); if (has_method("_notification_centity_resource_removed")) call("_notification_centity_resource_removed", data, resource); } //Equipment bool Spell::equip_should_deny(Ref data, int equip_slot, Ref item) { ERR_FAIL_COND_V(!data.is_valid(), false); if (has_method("_equip_should_deny")) if (call("_equip_should_deny", data, equip_slot, item)) return true; return false; } void Spell::equip_son_success(Ref data, int equip_slot, Ref item, Ref old_item, int bag_slot) { ERR_FAIL_COND(!data.is_valid()); if (has_method("_equip_son_success")) call("_equip_son_success", data, equip_slot, item, old_item, bag_slot); } void Spell::equip_son_fail(Ref data, int equip_slot, Ref item, Ref old_item, int bag_slot) { ERR_FAIL_COND(!data.is_valid()); if (has_method("_equip_son_fail")) call("_equip_son_fail", data, equip_slot, item, old_item, bag_slot); } void Spell::equip_con_success(Ref data, int equip_slot, Ref item, Ref old_item, int bag_slot) { ERR_FAIL_COND(!data.is_valid()); if (has_method("_equip_con_success")) call("_equip_con_success", data, equip_slot, item, old_item, bag_slot); } void Spell::equip_con_fail(Ref data, int equip_slot, Ref item, Ref old_item, int bag_slot) { ERR_FAIL_COND(!data.is_valid()); if (has_method("_equip_con_fail")) call("_equip_con_fail", data, equip_slot, item, old_item, bag_slot); } //Calculations / Queries void Spell::calculate_initial_damage(Ref data) { ERR_FAIL_COND(!data.is_valid() || data->receiver_get() == NULL); call("_calculate_initial_damage", data); } void Spell::handle_spell_damage(Ref data) { ERR_FAIL_COND(!data.is_valid() || data->receiver_get() == NULL); call("_handle_spell_damage", data); } void Spell::calculate_initial_heal(Ref data) { ERR_FAIL_COND(!data.is_valid() || data->receiver_get() == NULL); call("_calculate_initial_heal", data); } void Spell::handle_spell_heal(Ref data) { ERR_FAIL_COND(!data.is_valid() || data->receiver_get() == NULL); call("_handle_spell_heal", data); } void Spell::handle_projectile(Ref info) { ERR_FAIL_COND(!info.is_valid()); call("_handle_projectile", info); } void Spell::handle_effect(Ref info) { ERR_FAIL_COND(!info.is_valid()); call("_handle_effect", info); } void Spell::handle_gcd(Ref info) { ERR_FAIL_COND(!info.is_valid()); if (_global_cooldown_enabled && _cast_time_enabled) { float gcd = info->caster_get()->stat_gets_current(ESS::get_singleton()->stat_get_id("Global Cooldown")); info->caster_get()->gcd_starts(gcd); } } void Spell::handle_cooldown(Ref info) { ERR_FAIL_COND(!info.is_valid()); if (_cooldown > 0.00001) { info->caster_get()->cooldown_adds(_id, _cooldown); } } void Spell::setup_aura_data(Ref data, Ref info) { ERR_FAIL_COND(!data.is_valid() || !info.is_valid()); //always exists call("_setup_aura_data", data, info); } void Spell::aura_sapply_passives_damage_receive(Ref info) { ERR_FAIL_COND(!info.is_valid()); //always exists call("_aura_sapply_passives_damage_receive", info); } void Spell::aura_sapply_passives_damage_deal(Ref info) { ERR_FAIL_COND(!info.is_valid()); //always exists call("_aura_sapply_passives_damage_deal", info); } void Spell::aura_calculate_initial_damage(Ref aura_data, Ref info) { ERR_FAIL_COND(!aura_data.is_valid() || !info.is_valid()); //always exists call("_aura_calculate_initial_damage", aura_data, info); } void Spell::handle_aura_damage(Ref aura_data, Ref info) { ERR_FAIL_COND(!aura_data.is_valid() || !info.is_valid()); //always exists call("_handle_aura_damage", aura_data, info); } void Spell::aura_sapply_passives_heal_receive(Ref data) { ERR_FAIL_COND(!data.is_valid()); //always exists call("_aura_sapply_passives_heal_receive", data); } void Spell::aura_sapply_passives_heal_deal(Ref data) { ERR_FAIL_COND(!data.is_valid()); //always exists call("_aura_sapply_passives_heal_deal", data); } void Spell::aura_calculate_initial_heal(Ref aura_data, Ref info) { ERR_FAIL_COND(!aura_data.is_valid() || !info.is_valid()); //always exists call("_aura_calculate_initial_heal", aura_data, info); } void Spell::handle_aura_heal(Ref aura_data, Ref data) { ERR_FAIL_COND(!aura_data.is_valid() || !data.is_valid()); //always exists call("_handle_aura_heal", aura_data, data); } String Spell::get_name_translated() const { if (_text_translation_key != "") { return tr(_text_translation_key); } return get_name(); } String Spell::get_description(const int class_level, const int character_level) { return call("_get_description", class_level, character_level); } String Spell::_get_description(const int class_level, const int character_level) { String str; if (_text_translation_key != "") { str = tr(_text_translation_key + "_DESC"); } str = _text_description; int pos = str.find_char('%'); while (pos > 0) { if (pos == str.size() - 1) break; #if GODOT4 char32_t o = str[pos + 1]; #else CharType o = str[pos + 1]; #endif if (o == '#' || o == '$' || o == '%') { int nsp = str.find_char(' ', pos + 1); if (pos < 0) break; String prop = str.substr(pos + 2, nsp - pos - 2); StringName psm = prop; bool valid = false; Variant value = get(psm, &valid); if (valid) { if (o == '#') { value = Variant::evaluate(Variant::OP_MULTIPLY, value, class_level / static_cast(ESS::get_singleton()->get_max_class_level())); value = static_cast(value); } if (o == '$') { value = Variant::evaluate(Variant::OP_MULTIPLY, value, character_level / static_cast(ESS::get_singleton()->get_max_character_level())); value = static_cast(value); } str = str.replace(str.substr(pos, nsp - pos) + " ", value); } } pos = str.find_char('%', pos + 1); } return str; } String Spell::aura_get_name_translated() const { if (_aura_text_translation_key != "") { return tr(_aura_text_translation_key); } return get_name(); } String Spell::aura_get_description(const int class_level, const int character_level) { return call("_aura_get_description", class_level, character_level); } String Spell::_aura_get_description(const int class_level, const int character_level) { String str; if (_aura_text_translation_key != "") { str = tr(_aura_text_translation_key + "_DESC"); } str = _aura_text_description; int pos = str.find_char('%'); while (pos > 0) { if (pos == str.size() - 1) break; #if GODOT4 char32_t o = str[pos + 1]; #else CharType o = str[pos + 1]; #endif if (o == '#' || o == '$' || o == '%') { int nsp = str.find_char(' ', pos + 1); if (pos < 0) break; String prop = str.substr(pos + 2, nsp - pos - 2); StringName psm = prop; bool valid = false; Variant value = get(psm, &valid); if (valid) { if (o == '#') { value = Variant::evaluate(Variant::OP_MULTIPLY, value, class_level / static_cast(ESS::get_singleton()->get_max_class_level())); value = static_cast(value); } if (o == '$') { value = Variant::evaluate(Variant::OP_MULTIPLY, value, character_level / static_cast(ESS::get_singleton()->get_max_character_level())); value = static_cast(value); } str = str.replace(str.substr(pos, nsp - pos) + " ", value); } } pos = str.find_char('%', pos + 1); } return str; } Spell::Spell() { PLAYER_HIT_RADIUS = (float)0.5; _id = 1; _spell_type = SpellEnums::SPELL_TYPE_NONE; _spell_category = SpellEnums::SPELL_CATEGORY_NORMAL; _hide_from_actionbar = false; _cooldown = 0; _cast_time = 0; _target_type = SpellTargetType::SPELL_TARGET_TYPE_TARGET; _target_relation_type = TargetRelationType::TARGET_ENEMY; _level = 1; _rank = 0; _scale_with_level = ESS::get_singleton()->get_scale_spells_by_default(); _global_cooldown_enabled = true; _is_local_spell = false; _range_enabled = false; _range = 0; _damage_enabled = false; _damage_type = 0; _damage_min = 0; _damage_max = 0; _damage_scale_stat = 0; _damage_scale_coeff = 0; _heal_enabled = false; _heal_min = 0; _heal_max = 0; _heal_scale_stat = 0; _heal_scale_coeff = 0; _dispell_enabled = false; _dispell_count_min = 0; _dispell_count_max = 0; _dispell_aura_types = 0; _cast_time_enabled = false; _cast_time = 0; _needs_target = false; _can_move_while_casting = false; _interrupt_enabled = false; _interrupt_time = 0; _is_aoe = false; _aoe_targetType = SpellAOETargetType::SPELL_AOE_TARGET_TYPE_CASTER; _aoe_colliderType = SpellEnums::COLLIDER_TYPE_NONE; _aoe_radius = 0; _spell_cooldown_mainpulation_data_count = 0; _training_cost = 0; _training_required_skill_level = 0; _projectile_use_time = false; _projectile_time = 0; _projectile_use_speed = false; _projectile_speed = 0; _aura_permanent = false; _aura_ability_scale_data_id = 1; _aura_time = 0; _aura_tick = 0; _aura_type = SpellEnums::AURA_TYPE_NONE; _aura_is_debuff = false; _aura_hide = false; _aura_scale_with_level = ESS::get_singleton()->get_scale_spells_by_default(); _aura_damage_enabled = false; _aura_damage_type = 0; _aura_damage_min = 0; _aura_damage_max = 0; _aura_damage_can_crit = false; _aura_absorb_enabled = false; _aura_absorb_damage_type = 0; _aura_absorb_min = 0; _aura_absorb_max = 0; _aura_heal_enabled = false; _aura_heal_min = 0; _aura_heal_max = 0; _aura_heal_can_crit = false; _aura_dispell_enabled = false; _aura_dispell_count_min = 0; _aura_dispell_count_max = 0; _aura_dispell_aura_types = 0; _aura_add_states = 0; _aura_remove_effects_with_states = 0; _aura_supress_states = 0; _aura_stat_attribute_count = 0; _aura_trigger_count = 0; _aura_diminishing_return_enabled = false; _aura_diminishing_return_category = 0; } Spell::~Spell() { _spells_cast_on_caster.clear(); _spells_cast_on_target.clear(); _on_learn_cast_spells.clear(); _item_cost.unref(); _required_item.unref(); _resource_cost.unref(); _resource_give.unref(); _icon.unref(); _visual_spell_effects.unref(); _teaches_craft_recipe.unref(); _training_required_spell.unref(); _training_required_skill.unref(); _projectile_scene.unref(); _aura_teaches_spell.unref(); _aura_visual_spell_effects.unref(); _aura_damage_scaling_curve.unref(); _aura_absorb_scaling_curve.unref(); _aura_heal_scaling_curve.unref(); for (int i = 0; i < MAX_TRIGGER_DATA; ++i) { _aura_trigger_datas[i].spell.unref(); } _aura_talent_required_talent.unref(); _aura_talent_required_spell.unref(); } void Spell::_cast_starts(Ref info) { if (info->caster_get()->cast_is_castings()) { return; } if ((get_global_cooldown_enabled() && info->caster_get()->gcd_hass()) || info->caster_get()->category_cooldown_hass(spell_type_get()) || info->caster_get()->cooldown_hass(get_id())) { return; } if (!info->caster_get()->spell_hass_id(get_id())) { return; } if (cast_time_get_enabled()) { info->caster_get()->cast_starts(info); return; } info->caster_get()->cast_spell_successs(info); info->target_get()->notification_scast(SpellEnums::NOTIFICATION_CAST_FINISHED_TARGET, info); //if (get_projectile().is_valid()) { // handle_projectile(info); //} else { // handle_effect(info); //} handle_cooldown(info); handle_gcd(info); } void Spell::_cast_finishs(Ref info) { info->caster_get()->notification_scast(SpellEnums::NOTIFICATION_CAST_FINISHED, info); info->caster_get()->cast_spell_successs(info); if (INSTANCE_VALIDATE(info->target_get())) { info->target_get()->notification_scast(SpellEnums::NOTIFICATION_CAST_FINISHED_TARGET, info); } //if (get_projectile().is_valid()) { // handle_projectile(info); //} else { // handle_effect(info); //} handle_cooldown(info); } void Spell::_son_cast_player_moved(Ref info) { if (get_can_move_while_casting()) { info->caster_get()->cast_fails(); } } void Spell::_son_spell_hit(Ref info) { handle_effect(info); } void Spell::_calculate_initial_damage(Ref data) { Math::randomize(); data->damage_set(damage_get_min() + (damage_get_max() - damage_get_min()) * Math::randf()); } void Spell::_handle_spell_damage(Ref data) { calculate_initial_damage(data); data->dealer_get()->sdeal_damage_to(data); } void Spell::_calculate_initial_heal(Ref data) { Math::randomize(); data->heal_set(heal_get_min() + (heal_get_max() - heal_get_min()) * Math::randf()); } void Spell::_handle_spell_heal(Ref data) { calculate_initial_heal(data); data->dealer_get()->sdeal_heal_to(data); } void Spell::_handle_projectile(Ref info) { if (_projectile_scene.is_valid()) { Node *projectile = _projectile_scene->instantiate(); Node *p = info->caster_get()->get_parent(); ERR_FAIL_COND(!INSTANCE_VALIDATE(p)); p->add_child(projectile); if (projectile->has_method("setup_projectile")) projectile->call("setup_projectile", info); } } void Spell::_handle_effect(Ref info) { /* # var ok : bool = false # if (target_relation_type & TARGET_SELF): # ok = true # if not ok and (target_relation_type & TARGET_ENEMY and info.target is Entity): # ok = true # # if not ok and (target_relation_type & TARGET_FRIENDLY and info.target is Player): # ok = true # if not ok: # return */ bool has_target = INSTANCE_VALIDATE(info->target_get()); if (_target_type == SPELL_TARGET_TYPE_TARGET) { if (!has_target) return; } else if (_target_type == SPELL_TARGET_TYPE_SELF) { info->target_set(info->caster_get()); } if (_damage_enabled && has_target) { Ref sdi; sdi.instantiate(); sdi->spell_source_set(Ref(this)); sdi->dealer_set(info->caster_get()); sdi->receiver_set(info->target_get()); handle_spell_damage(sdi); } if (is_aura()) { Ref ad; if (aura_get_aura_group().is_valid()) { ad = info->target_get()->aura_gets_with_group_by_bind(info->caster_get(), aura_get_aura_group()); } else { ad = info->target_get()->aura_gets_by(info->caster_get(), get_id()); } if (ad.is_valid()) { info->target_get()->aura_removes_exact(ad); } Ref aai; aai.instantiate(); aai->caster_set(info->caster_get()); aai->target_set(info->target_get()); aai->spell_scale_set(1); aai->set_aura(Ref(this)); aura_sapply(aai); } for (int i = 0; i < _spells_cast_on_caster.size(); ++i) { Ref spell = _spells_cast_on_caster.get(i); if (!spell.is_valid()) { continue; } Ref sci; sci.instantiate(); sci->caster_set(info->caster_get()); sci->target_set(info->caster_get()); sci->has_cast_time_set(spell->cast_time_get_enabled()); sci->cast_time_set(spell->cast_time_get()); sci->spell_scale_set(info->spell_scale_get()); sci->set_spell(spell); spell->cast_starts(sci); } if (has_target) { for (int i = 0; i < _spells_cast_on_target.size(); ++i) { Ref spell = _spells_cast_on_target.get(i); if (!spell.is_valid()) { continue; } Ref sci; sci.instantiate(); sci->caster_set(info->caster_get()); sci->target_set(info->target_get()); sci->has_cast_time_set(spell->cast_time_get_enabled()); sci->cast_time_set(spell->cast_time_get()); sci->spell_scale_set(info->spell_scale_get()); sci->set_spell(spell); spell->cast_starts(sci); } } } void Spell::_aura_sapply(Ref info) { ERR_FAIL_COND(info->target_get() == NULL || info->caster_get() == NULL || !info->get_aura().is_valid()); Ref ad = info->target_get()->aura_gets_by(info->caster_get(), _id); if (!ad.is_valid()) { ad.instantiate(); setup_aura_data(ad, info); Entity *owner = ad->get_owner(); for (int i = 0; i < _aura_stat_attribute_count; ++i) { owner->stat_mod(_aura_stat_attributes[i].stat, _aura_stat_attributes[i].base_mod, _aura_stat_attributes[i].bonus_mod, _aura_stat_attributes[i].percent_mod); } if (_aura_add_states != 0) { for (int i = 0; i < EntityEnums::ENTITY_STATE_TYPE_INDEX_MAX; ++i) { int t = 1 << i; if ((_aura_add_states & t) != 0) { info->target_get()->adds_state_ref(i); } } } info->target_get()->aura_adds(ad); } else { ad->set_remaining_time(_aura_time); } } void Spell::_aura_sdeapply(Ref data) { ERR_FAIL_COND(data->get_owner() == NULL || data->caster_get() == NULL || !data->get_aura().is_valid()); Entity *owner = data->get_owner(); for (int i = 0; i < _aura_stat_attribute_count; ++i) { owner->stat_mod(_aura_stat_attributes[i].stat, -_aura_stat_attributes[i].base_mod, -_aura_stat_attributes[i].bonus_mod, -_aura_stat_attributes[i].percent_mod); } if (_aura_add_states != 0) { for (int i = 0; i < EntityEnums::ENTITY_STATE_TYPE_INDEX_MAX; ++i) { int t = 1 << i; if ((_aura_add_states & t) != 0) { data->get_owner()->removes_state_ref(i); } } } } void Spell::_aura_sadd(Ref aura) { ERR_FAIL_COND(aura->get_owner() == NULL); //sapply(aura); aura->get_owner()->aura_removes(aura); aura->get_owner()->aura_adds(aura); } void Spell::_aura_sremove(Ref aura) { ERR_FAIL_COND(aura->get_owner() == NULL); aura_sdeapply(aura); aura->get_owner()->aura_removes(aura); } void Spell::_aura_removes_expired(Ref aura) { ERR_FAIL_COND(aura->get_owner() == NULL); aura_sdeapply(aura); aura->get_owner()->aura_removes_expired(aura); } void Spell::_aura_removes_dispell(Ref aura) { ERR_FAIL_COND(aura->get_owner() == NULL); aura_sdeapply(aura); aura->get_owner()->aura_removes_dispelled(aura); } void Spell::_aura_supdate(Ref aura, float delta) { bool remove = false; remove = aura->update(delta); //ontick while (aura->get_unhandled_ticks() > 0) { if (aura->damage_get() != 0) { Ref dpd = Ref(memnew(SpellDamageInfo())); dpd->aura_source_set(Ref(this)); dpd->dealer_set(aura->caster_get()); dpd->receiver_set(aura->get_owner()); handle_aura_damage(aura, dpd); } if (aura->heal_get() != 0) { Ref shi = Ref(memnew(SpellHealInfo())); shi->aura_source_set(Ref(this)); shi->dealer_set(aura->caster_get()); shi->receiver_set(aura->get_owner()); handle_aura_heal(aura, shi); } aura->set_unhandled_ticks(aura->get_unhandled_ticks() - 1); } if (remove) { aura_removes_expired(aura); } } void Spell::_setup_aura_data(Ref data, Ref info) { ERR_FAIL_COND(!INSTANCE_VALIDATE(info->caster_get())); data->set_aura(Ref(this)); data->set_aura_id(get_id()); data->set_owner(info->target_get()); data->caster_set(info->caster_get()); data->set_tick(info->get_aura()->aura_get_tick()); if (aura_get_time() > 0.2) { data->set_is_timed(true); data->set_remaining_time(aura_get_time()); } else { data->set_is_timed(false); } if (aura_damage_get_enabled()) { aura_calculate_initial_damage(data, info); } if (aura_heal_get_enabled()) { aura_calculate_initial_heal(data, info); } } void Spell::_aura_sapply_passives_damage_receive(Ref info) { } void Spell::_aura_sapply_passives_damage_deal(Ref info) { } void Spell::_aura_calculate_initial_damage(Ref aura_data, Ref info) { int min_damage = aura_damage_get_min(); int max_damage = aura_damage_get_max(); Math::randomize(); int damage = min_damage + Math::rand() % (max_damage - min_damage); if (aura_get_scale_with_level()) { damage = static_cast(damage * static_cast(info->caster_get()->gets_level()) / static_cast(ESS::get_singleton()->get_max_character_level())); } aura_data->damage_set(damage); } void Spell::_handle_aura_damage(Ref aura_data, Ref info) { if (info->dealer_get() && !INSTANCE_VALIDATE(info->dealer_get())) { info->dealer_set(NULL); } info->damage_set(aura_data->damage_get()); info->aura_source_set(Ref(this)); if (info->dealer_get()) { info->dealer_get()->sdeal_damage_to(info); } else { info->receiver_get()->stake_damage(info); } } void Spell::_aura_sapply_passives_heal_receive(Ref data) { ERR_FAIL_COND(!data.is_valid()); } void Spell::_aura_sapply_passives_heal_deal(Ref data) { ERR_FAIL_COND(!data.is_valid()); } void Spell::_aura_calculate_initial_heal(Ref aura_data, Ref info) { int min_heal = aura_heal_get_min(); int max_heal = aura_heal_get_max(); Math::randomize(); int heal = min_heal + Math::rand() % (max_heal - min_heal); if (aura_get_scale_with_level()) { heal = static_cast(heal * static_cast(info->caster_get()->gets_level()) / static_cast(ESS::get_singleton()->get_max_character_level())); } aura_data->heal_set(heal); } void Spell::_handle_aura_heal(Ref aura_data, Ref info) { if (info->dealer_get() && !INSTANCE_VALIDATE(info->dealer_get())) { info->dealer_set(NULL); } info->heal_set(aura_data->heal_get()); if (info->dealer_get()) { info->dealer_get()->sdeal_heal_to(info); } else { info->receiver_get()->stake_heal(info); } } void Spell::_validate_property(PropertyInfo &property) const { String prop = property.name; if (prop.begins_with("aura_stat_attribute_")) { if (prop.ends_with("count")) return; int frame = prop.get_slicec('/', 0).get_slicec('_', 2).to_int(); if (frame >= _aura_stat_attribute_count) { property.usage = 0; } if (property.name.ends_with("stat")) property.hint_string = ESS::get_singleton()->stat_get_string(); } else if (prop == "diminishing_return_category") { property.hint_string = ESS::get_singleton()->dminishing_return_categories_get(); } else if (prop.begins_with("aura_trigger_")) { if (prop.ends_with("count")) return; int frame = prop.get_slicec('/', 0).get_slicec('_', 1).to_int(); if (frame >= _aura_trigger_count) { property.usage = 0; } else { if (prop.ends_with("notification_data")) { switch (_aura_trigger_datas[frame].notification_type) { case SpellEnums::TRIGGER_NOTIFICATION_TYPE_AURA: property.hint = PROPERTY_HINT_ENUM; property.hint_string = SpellEnums::BINDING_STRING_NOTIFICATION_AURAS; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_DAMAGE: property.hint = PROPERTY_HINT_ENUM; property.hint_string = SpellEnums::BINDING_STRING_NOTIFICATION_DAMAGES; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_HEAL: property.hint = PROPERTY_HINT_ENUM; property.hint_string = SpellEnums::BINDING_STRING_NOTIFICATION_HEALS; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_CAST: property.hint = PROPERTY_HINT_ENUM; property.hint_string = SpellEnums::BINDING_STRING_NOTIFICATION_CASTS; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_DEATH: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_COOLDOWN_ADDED: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_COOLDOWN_REMOVED: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_CATEGORY_COOLDOWN_ADDED: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_CATEGORY_COOLDOWN_REMOVED: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_GCD_STARTED: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_GCD_FINISHED: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_XP_GAINED: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_CLASS_LEVELUP: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_CHARACTER_LEVELUP: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_ENTITY_RESOURCE_ADDED: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_ENTITY_RESOURCE_REMOVED: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_AURA_CUSTOM: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_DAMAGE_CUSTOM: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_HEAL_CUSTOM: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_CAST_CUSTOM: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; case SpellEnums::TRIGGER_NOTIFICATION_TYPE_CUSTOM: property.hint = PROPERTY_HINT_NONE; property.hint_string = ""; break; default: break; } } } } else if (property.name.ends_with("_stat")) { property.hint_string = ESS::get_singleton()->stat_get_string(); } } void Spell::_bind_methods() { //Commands ClassDB::bind_method(D_METHOD("cast_starts", "info"), &Spell::cast_starts); ClassDB::bind_method(D_METHOD("cast_starts_triggered", "info"), &Spell::cast_starts_triggered); ClassDB::bind_method(D_METHOD("cast_interrupts", "info"), &Spell::cast_interrupts); ClassDB::bind_method(D_METHOD("cast_finishs", "info"), &Spell::cast_finishs); //GDVIRTUAL_BIND("_cast_starts", "info", "SpellCastInfo"); //GDVIRTUAL_BIND("_cast_starts_triggered", "info", "SpellCastInfo"); //GDVIRTUAL_BIND("_cast_interrupts", "info", "SpellCastInfo"); //GDVIRTUAL_BIND("_cast_finishs", "info", "SpellCastInfo"); //Aura Commands ClassDB::bind_method(D_METHOD("aura_sapply", "info"), &Spell::aura_sapply); ClassDB::bind_method(D_METHOD("aura_sdeapply", "aura"), &Spell::aura_sdeapply); ClassDB::bind_method(D_METHOD("aura_sadd", "aura"), &Spell::aura_sadd); ClassDB::bind_method(D_METHOD("aura_sremove", "aura"), &Spell::aura_sremove); ClassDB::bind_method(D_METHOD("aura_removes_expired", "aura"), &Spell::aura_removes_expired); ClassDB::bind_method(D_METHOD("aura_removes_dispell", "aura"), &Spell::aura_removes_dispell); ClassDB::bind_method(D_METHOD("aura_supdate", "aura", "delta"), &Spell::aura_supdate); //GDVIRTUAL_BIND("_aura_sapply", "info", "AuraApplyInfo"); //GDVIRTUAL_BIND("_aura_sdeapply", "info", "AuraData"); //GDVIRTUAL_BIND("_aura_sadd", "aura", "AuraData"); //GDVIRTUAL_BIND("_aura_sremove", "aura", "AuraData"); //GDVIRTUAL_BIND("_aura_removes_expired", "info", "AuraData"); //GDVIRTUAL_BIND("_aura_removes_dispell", "info", "AuraData"); //GDVIRTUAL_BIND("_aura_supdate", "info", "AuraData", "delta"); ClassDB::bind_method(D_METHOD("_aura_sapply", "info"), &Spell::_aura_sapply); ClassDB::bind_method(D_METHOD("_aura_sdeapply", "aura"), &Spell::_aura_sdeapply); ClassDB::bind_method(D_METHOD("_aura_sadd", "aura"), &Spell::_aura_sadd); ClassDB::bind_method(D_METHOD("_aura_sremove", "aura"), &Spell::_aura_sremove); ClassDB::bind_method(D_METHOD("_aura_removes_expired", "aura"), &Spell::_aura_removes_expired); ClassDB::bind_method(D_METHOD("_aura_removes_dispell", "aura"), &Spell::_aura_removes_dispell); ClassDB::bind_method(D_METHOD("_aura_supdate", "aura", "delta"), &Spell::_aura_supdate); //Eventhandlers ClassDB::bind_method(D_METHOD("son_cast_player_moved", "info"), &Spell::son_cast_player_moved); ClassDB::bind_method(D_METHOD("son_cast_damage_received", "info"), &Spell::son_cast_damage_received); ClassDB::bind_method(D_METHOD("son_spell_hit", "info"), &Spell::son_spell_hit); ClassDB::bind_method(D_METHOD("son_physics_process", "info", "delta"), &Spell::son_physics_process); //GDVIRTUAL_BIND("_son_cast_player_moved", "info", "SpellCastInfo"); //GDVIRTUAL_BIND("_son_cast_damage_received", "info", "SpellCastInfo"); //GDVIRTUAL_BIND("_son_spell_hit", "info", "SpellCastInfo"); //GDVIRTUAL_BIND("_son_physics_process", "info", "SpellCastInfo", "delta"); //Clientside Event Handlers //GDVIRTUAL_BIND("_notification_scast", "what", "info", "SpellCastInfo"); ClassDB::bind_method(D_METHOD("notification_scast", "what", "info"), &Spell::notification_scast); //GDVIRTUAL_BIND("_notification_ccast", "what", "info", "SpellCastInfo"); ClassDB::bind_method(D_METHOD("notification_ccast", "what", "info"), &Spell::notification_ccast); //Aura EventHandlers //GDVIRTUAL_BIND("_notification_saura", "what", "data", "AuraData"); //GDVIRTUAL_BIND("_notification_sheal", "what", "data", "AuraData", "data", "SpellHealInfo"); //GDVIRTUAL_BIND("_notification_aura_scast", "what", "data", "AuraData", "info", "SpellCastInfo"); //GDVIRTUAL_BIND("_notification_sdamage", "what", "data", "AuraData", "data", "SpellDamageInfo"); ClassDB::bind_method(D_METHOD("notification_saura", "what", "data"), &Spell::notification_saura); ClassDB::bind_method(D_METHOD("notification_sheal", "what", "aura", "info"), &Spell::notification_sheal); ClassDB::bind_method(D_METHOD("notification_aura_scast", "what", "aura", "info"), &Spell::notification_aura_scast); ClassDB::bind_method(D_METHOD("notification_sdamage", "what", "aura", "info"), &Spell::notification_sdamage); ClassDB::bind_method(D_METHOD("son_remove", "aura"), &Spell::son_remove); ClassDB::bind_method(D_METHOD("son_remove_expired", "aura"), &Spell::son_remove_expired); ClassDB::bind_method(D_METHOD("son_remove_dispell", "aura"), &Spell::son_remove_dispell); ClassDB::bind_method(D_METHOD("notification_sdeath", "data"), &Spell::notification_sdeath); ClassDB::bind_method(D_METHOD("notification_scooldown_added", "data", "cooldown"), &Spell::notification_scooldown_added); ClassDB::bind_method(D_METHOD("notification_scooldown_removed", "data", "cooldown"), &Spell::notification_scooldown_removed); ClassDB::bind_method(D_METHOD("notification_scategory_cooldown_added", "data", "category_cooldown"), &Spell::notification_scategory_cooldown_added); ClassDB::bind_method(D_METHOD("notification_scategory_cooldown_removed", "data", "category_cooldown"), &Spell::notification_scategory_cooldown_removed); ClassDB::bind_method(D_METHOD("notification_sgcd_started", "data", "gcd"), &Spell::notification_sgcd_started); ClassDB::bind_method(D_METHOD("notification_sgcd_finished", "data"), &Spell::notification_sgcd_finished); ClassDB::bind_method(D_METHOD("son_physics_process_aura", "data"), &Spell::son_physics_process_aura); ClassDB::bind_method(D_METHOD("notification_sxp_gained", "data", "value"), &Spell::notification_sxp_gained); ClassDB::bind_method(D_METHOD("notification_slevel_up", "data", "value"), &Spell::notification_slevel_up); ClassDB::bind_method(D_METHOD("notification_sentity_resource_added", "data", "value"), &Spell::notification_sentity_resource_added); ClassDB::bind_method(D_METHOD("notification_sentity_resource_removed", "data", "value"), &Spell::notification_sentity_resource_removed); //GDVIRTUAL_BIND("_son_remove", "data", "AuraData"); //GDVIRTUAL_BIND("_son_remove_expired", "data", "AuraData"); //GDVIRTUAL_BIND("_son_remove_dispell", "data", "AuraData"); //GDVIRTUAL_BIND("_notification_sdeath", "data", "AuraData"); //GDVIRTUAL_BIND("_notification_scooldown_added", "data", "AuraData", "id", "value"); //GDVIRTUAL_BIND("_notification_scooldown_removed", "data", "AuraData", "id", "value"); //GDVIRTUAL_BIND("_notification_scategory_cooldown_added", "data", "AuraData", "id", "value"); //GDVIRTUAL_BIND("_notification_scategory_cooldown_removed", "data", "AuraData", "id", "value"); //GDVIRTUAL_BIND("_notification_sgcd_started", "data", "AuraData", "gcd"); //GDVIRTUAL_BIND("_notification_sgcd_finished", "data", "AuraData"); //GDVIRTUAL_BIND("_son_physics_process_aura", "data", "AuraData"); //GDVIRTUAL_BIND("_notification_sxp_gained", "data", "AuraData", "value"); //GDVIRTUAL_BIND("_notification_slevel_up", "data", "AuraData", "value"); //GDVIRTUAL_BIND("_notification_sentity_resource_added", "data", "AuraData", "value"); //GDVIRTUAL_BIND("_notification_sentity_resource_removed", "data", "AuraData", "value"); //Aura Clientside Event Handlers //GDVIRTUAL_BIND("_notification_caura", "what", "data", "AuraData"); //GDVIRTUAL_BIND("_notification_cheal", "what", "data", "AuraData", "data", "SpellHealInfo"); //GDVIRTUAL_BIND("_notification_aura_ccast", "what", "data", "AuraData", "info", "SpellCastInfo"); //GDVIRTUAL_BIND("_notification_cdamage", "what", "data", "AuraData", "data", "SpellDamageInfo"); ClassDB::bind_method(D_METHOD("notification_caura", "what", "data"), &Spell::notification_caura); ClassDB::bind_method(D_METHOD("notification_cheal", "what", "aura", "info"), &Spell::notification_cheal); ClassDB::bind_method(D_METHOD("notification_aura_ccast", "what", "aura", "info"), &Spell::notification_aura_ccast); ClassDB::bind_method(D_METHOD("notification_cdamage", "what", "aura", "info"), &Spell::notification_cdamage); ClassDB::bind_method(D_METHOD("notification_cdeath", "data"), &Spell::notification_cdeath); ClassDB::bind_method(D_METHOD("notification_ccooldown_added", "data", "info"), &Spell::notification_ccooldown_added); ClassDB::bind_method(D_METHOD("notification_ccooldown_removed", "data", "info"), &Spell::notification_ccooldown_removed); ClassDB::bind_method(D_METHOD("notification_ccategory_cooldown_added", "data", "info"), &Spell::notification_ccategory_cooldown_added); ClassDB::bind_method(D_METHOD("notification_ccategory_cooldown_removed", "data", "info"), &Spell::notification_ccategory_cooldown_removed); ClassDB::bind_method(D_METHOD("notification_cgcd_started", "data", "info"), &Spell::notification_cgcd_started); ClassDB::bind_method(D_METHOD("notification_cgcd_finished", "data"), &Spell::notification_cgcd_finished); ClassDB::bind_method(D_METHOD("notification_cxp_gained", "data", "value"), &Spell::notification_cxp_gained); ClassDB::bind_method(D_METHOD("notification_clevel_up", "data", "value"), &Spell::notification_clevel_up); ClassDB::bind_method(D_METHOD("notification_centity_resource_added", "data", "value"), &Spell::notification_centity_resource_added); ClassDB::bind_method(D_METHOD("notification_centity_resource_removed", "data", "value"), &Spell::notification_centity_resource_removed); //GDVIRTUAL_BIND("_con_cast_failed", "data", "AuraData", "info", "SpellCastInfo"); //GDVIRTUAL_BIND("_con_cast_started", "data", "AuraData", "info", "SpellCastInfo"); //GDVIRTUAL_BIND("_con_cast_state_changed", "data", "AuraData", "info", "SpellCastInfo"); //GDVIRTUAL_BIND("_con_cast_finished", "data", "AuraData", "info", "SpellCastInfo"); //GDVIRTUAL_BIND("_con_spell_cast_success", "data", "AuraData", "info", "SpellCastInfo"); //GDVIRTUAL_BIND("_notification_cdeath", "data", "AuraData"); //GDVIRTUAL_BIND("_notification_ccooldown_added", "data", "AuraData", "id", "value"); //GDVIRTUAL_BIND("_notification_ccooldown_removed", "data", "AuraData", "id", "value"); //GDVIRTUAL_BIND("_notification_ccategory_cooldown_added", "data", "AuraData", "id", "value"); //GDVIRTUAL_BIND("_notification_ccategory_cooldown_removed", "data", "AuraData", "id", "value"); //GDVIRTUAL_BIND("_con_aura_added", "data", "AuraData"); //GDVIRTUAL_BIND("_con_aura_removed", "data", "AuraData"); //GDVIRTUAL_BIND("_con_aura_refresh", "data", "AuraData"); //GDVIRTUAL_BIND("_con_damage_dealt", "data", "AuraData", "info", "SpellDamageInfo"); //GDVIRTUAL_BIND("_con_dealt_damage", "data", "AuraData", "info", "SpellDamageInfo"); //GDVIRTUAL_BIND("_con_heal_dealt", "data", "AuraData", "info", "SpellHealInfo"); //GDVIRTUAL_BIND("_con_dealt_heal", "data", "AuraData", "info", "SpellHealInfo"); //GDVIRTUAL_BIND("_notification_cgcd_started", "data", "AuraData", "gcd"); //GDVIRTUAL_BIND("_notification_cgcd_finished", "data", "AuraData"); //GDVIRTUAL_BIND("_notification_cxp_gained", "data", "AuraData", "value"); //GDVIRTUAL_BIND("_notification_clevel_up", "data", "AuraData", "value"); //GDVIRTUAL_BIND("_notification_centity_resource_added", "data", "AuraData", "value"); //GDVIRTUAL_BIND("_notification_centity_resource_removed", "data", "AuraData", "value"); //Equipment //GDVIRTUAL_BIND("_equip_should_deny", "data", "AuraData", "equip_slot", "item", "ItemInstance"); //GDVIRTUAL_BIND("_equip_son_success", "data", "AuraData", "equip_slot", "item", "ItemInstance", "old_item", "ItemInstance", "bag_slot"); //GDVIRTUAL_BIND("_equip_son_fail", "data", "AuraData", "equip_slot", "item", "ItemInstance", "old_item", "ItemInstance", "bag_slot"); //GDVIRTUAL_BIND("_equip_con_success", "data", "AuraData", "equip_slot", "item", "ItemInstance", "old_item", "ItemInstance", "bag_slot"); //GDVIRTUAL_BIND("_equip_con_fail", "data", "AuraData", "equip_slot", "item", "ItemInstance", "old_item", "ItemInstance", "bag_slot"); ClassDB::bind_method(D_METHOD("equip_should_deny", "data", "equip_slot", "item"), &Spell::equip_should_deny); ClassDB::bind_method(D_METHOD("equip_son_success", "data", "equip_slot", "item", "old_item", "bag_slot"), &Spell::equip_son_success); ClassDB::bind_method(D_METHOD("equip_son_fail", "data", "equip_slot", "item", "old_item", "bag_slot"), &Spell::equip_son_fail); ClassDB::bind_method(D_METHOD("equip_con_success", "data", "equip_slot", "item", "old_item", "bag_slot"), &Spell::equip_con_success); ClassDB::bind_method(D_METHOD("equip_con_fail", "data", "equip_slot", "item", "old_item", "bag_slot"), &Spell::equip_con_fail); //Calculations / Queries ClassDB::bind_method(D_METHOD("calculate_initial_damage", "data"), &Spell::calculate_initial_damage); ClassDB::bind_method(D_METHOD("handle_spell_damage", "data"), &Spell::handle_spell_damage); //GDVIRTUAL_BIND("_calculate_initial_damage", "data", "SpellDamageInfo"); //GDVIRTUAL_BIND("_handle_spell_damage", "data", "SpellDamageInfo"); ClassDB::bind_method(D_METHOD("calculate_initial_heal", "data"), &Spell::calculate_initial_heal); ClassDB::bind_method(D_METHOD("handle_spell_heal", "data"), &Spell::handle_spell_heal); //GDVIRTUAL_BIND("_calculate_initial_heal", "data", "SpellHealInfo"); //GDVIRTUAL_BIND("_handle_spell_heal", "data", "SpellHealInfo"); ClassDB::bind_method(D_METHOD("handle_projectile", "info"), &Spell::handle_projectile); ClassDB::bind_method(D_METHOD("handle_effect", "info"), &Spell::handle_effect); //GDVIRTUAL_BIND("_handle_projectile", "info", "SpellCastInfo"); //GDVIRTUAL_BIND("_handle_effect", "info", "SpellCastInfo"); ClassDB::bind_method(D_METHOD("handle_gcd", "info"), &Spell::handle_gcd); ClassDB::bind_method(D_METHOD("handle_cooldown", "info"), &Spell::handle_cooldown); //Implementations ClassDB::bind_method(D_METHOD("_cast_starts", "info"), &Spell::_cast_starts); ClassDB::bind_method(D_METHOD("_cast_finishs", "info"), &Spell::_cast_finishs); ClassDB::bind_method(D_METHOD("_son_cast_player_moved", "info"), &Spell::_son_cast_player_moved); ClassDB::bind_method(D_METHOD("_son_spell_hit", "info"), &Spell::_son_spell_hit); ClassDB::bind_method(D_METHOD("_calculate_initial_damage", "info"), &Spell::_calculate_initial_damage); ClassDB::bind_method(D_METHOD("_handle_spell_damage", "info"), &Spell::_handle_spell_damage); ClassDB::bind_method(D_METHOD("_calculate_initial_heal", "info"), &Spell::_calculate_initial_heal); ClassDB::bind_method(D_METHOD("_handle_spell_heal", "info"), &Spell::_handle_spell_heal); ClassDB::bind_method(D_METHOD("_handle_projectile", "info"), &Spell::_handle_projectile); ClassDB::bind_method(D_METHOD("_handle_effect", "info"), &Spell::_handle_effect); //Aura Calculations / Queries ClassDB::bind_method(D_METHOD("setup_aura_data", "data", "info"), &Spell::setup_aura_data); //GDVIRTUAL_BIND("_setup_aura_data", "data", "AuraData", "info", "AuraApplyInfo"); ClassDB::bind_method(D_METHOD("_setup_aura_data", "data", "info"), &Spell::_setup_aura_data); //damage ClassDB::bind_method(D_METHOD("aura_sapply_passives_damage_receive", "data"), &Spell::aura_sapply_passives_damage_receive); ClassDB::bind_method(D_METHOD("aura_sapply_passives_damage_deal", "data"), &Spell::aura_sapply_passives_damage_deal); ClassDB::bind_method(D_METHOD("aura_calculate_initial_damage", "aura_data", "info"), &Spell::aura_calculate_initial_damage); ClassDB::bind_method(D_METHOD("handle_aura_damage", "aura_data", "data"), &Spell::handle_aura_damage); //GDVIRTUAL_BIND("_aura_sapply_passives_damage_receive", "data", "SpellDamageInfo"); //GDVIRTUAL_BIND("_aura_sapply_passives_damage_deal", "data", "SpellDamageInfo"); //GDVIRTUAL_BIND("_aura_calculate_initial_damage", "data", "AuraData", "info", "AuraApplyInfo"); //GDVIRTUAL_BIND("_handle_aura_damage", "data", "AuraData", "info", "SpellDamageInfo"); ClassDB::bind_method(D_METHOD("_aura_sapply_passives_damage_receive", "info"), &Spell::_aura_sapply_passives_damage_receive); ClassDB::bind_method(D_METHOD("_aura_sapply_passives_damage_deal", "info"), &Spell::_aura_sapply_passives_damage_deal); ClassDB::bind_method(D_METHOD("_aura_calculate_initial_damage", "aura_data", "info"), &Spell::_aura_calculate_initial_damage); ClassDB::bind_method(D_METHOD("_handle_aura_damage", "aura_data", "info"), &Spell::_handle_aura_damage); //heal ClassDB::bind_method(D_METHOD("aura_sapply_passives_heal_receive", "data"), &Spell::aura_sapply_passives_heal_receive); ClassDB::bind_method(D_METHOD("aura_sapply_passives_heal_deal", "data"), &Spell::aura_sapply_passives_heal_deal); ClassDB::bind_method(D_METHOD("aura_calculate_initial_heal", "aura_data", "info"), &Spell::aura_calculate_initial_heal); ClassDB::bind_method(D_METHOD("handle_aura_heal", "aura_data", "data"), &Spell::handle_aura_heal); //GDVIRTUAL_BIND("_aura_sapply_passives_heal_receive", "info", "SpellDamageInfo"); //GDVIRTUAL_BIND("_aura_sapply_passives_heal_deal", "info", "SpellDamageInfo"); //GDVIRTUAL_BIND("_aura_calculate_initial_heal", "aura_data", "AuraData", "info", "AuraApplyInfo"); //GDVIRTUAL_BIND("_handle_aura_heal", "aura_data", "AuraData", "spell_heal_info", "SpellHealInfo"); ClassDB::bind_method(D_METHOD("_aura_sapply_passives_heal_receive", "info"), &Spell::_aura_sapply_passives_heal_receive); ClassDB::bind_method(D_METHOD("_aura_sapply_passives_heal_deal", "info"), &Spell::_aura_sapply_passives_heal_deal); ClassDB::bind_method(D_METHOD("_aura_calculate_initial_heal", "aura_data", "info"), &Spell::_aura_calculate_initial_heal); ClassDB::bind_method(D_METHOD("_handle_aura_heal", "aura_data", "info"), &Spell::_handle_aura_heal); //Properties ClassDB::bind_method(D_METHOD("get_id"), &Spell::get_id); ClassDB::bind_method(D_METHOD("set_id", "value"), &Spell::set_id); ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id"); ClassDB::bind_method(D_METHOD("spell_type_get"), &Spell::spell_type_get); ClassDB::bind_method(D_METHOD("spell_type_set", "value"), &Spell::spell_type_set); ADD_PROPERTY(PropertyInfo(Variant::INT, "spell_type", PROPERTY_HINT_FLAGS, SpellEnums::BINDING_STRING_SPELL_TYPES), "spell_type_set", "spell_type_get"); ClassDB::bind_method(D_METHOD("get_spell_category"), &Spell::get_spell_category); ClassDB::bind_method(D_METHOD("set_spell_category", "value"), &Spell::set_spell_category); ADD_PROPERTY(PropertyInfo(Variant::INT, "spell_category", PROPERTY_HINT_ENUM, SpellEnums::BINDING_STRING_SPELL_CATEGORY), "set_spell_category", "get_spell_category"); ClassDB::bind_method(D_METHOD("get_hide_from_actionbar"), &Spell::get_hide_from_actionbar); ClassDB::bind_method(D_METHOD("set_hide_from_actionbar", "value"), &Spell::set_hide_from_actionbar); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_from_actionbar"), "set_hide_from_actionbar", "get_hide_from_actionbar"); ClassDB::bind_method(D_METHOD("get_target_type"), &Spell::get_target_type); ClassDB::bind_method(D_METHOD("set_target_type", "value"), &Spell::set_target_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "target_type", PROPERTY_HINT_ENUM, "Self, Target, Around, Front, Around Target"), "set_target_type", "get_target_type"); ClassDB::bind_method(D_METHOD("get_target_relation_type"), &Spell::get_target_relation_type); ClassDB::bind_method(D_METHOD("set_target_relation_type", "value"), &Spell::set_target_relation_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "target_relation_type", PROPERTY_HINT_FLAGS, "Self, Enemy, Friendly"), "set_target_relation_type", "get_target_relation_type"); ClassDB::bind_method(D_METHOD("get_level"), &Spell::get_level); ClassDB::bind_method(D_METHOD("set_level", "value"), &Spell::set_level); ADD_PROPERTY(PropertyInfo(Variant::INT, "level"), "set_level", "get_level"); ClassDB::bind_method(D_METHOD("get_rank"), &Spell::get_rank); ClassDB::bind_method(D_METHOD("set_rank", "value"), &Spell::set_rank); ADD_PROPERTY(PropertyInfo(Variant::INT, "rank"), "set_rank", "get_rank"); ClassDB::bind_method(D_METHOD("get_is_local_spell"), &Spell::get_is_local_spell); ClassDB::bind_method(D_METHOD("set_is_local_spell", "value"), &Spell::set_is_local_spell); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_local_spell"), "set_is_local_spell", "get_is_local_spell"); ClassDB::bind_method(D_METHOD("get_icon"), &Spell::get_icon); ClassDB::bind_method(D_METHOD("set_icon", "value"), &Spell::set_icon); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_icon", "get_icon"); ClassDB::bind_method(D_METHOD("get_needs_target"), &Spell::get_needs_target); ClassDB::bind_method(D_METHOD("set_needs_target", "value"), &Spell::set_needs_target); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "needs_target"), "set_needs_target", "get_needs_target"); ClassDB::bind_method(D_METHOD("get_scale_with_level"), &Spell::get_scale_with_level); ClassDB::bind_method(D_METHOD("set_scale_with_level", "value"), &Spell::set_scale_with_level); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scale_with_level"), "set_scale_with_level", "get_scale_with_level"); ClassDB::bind_method(D_METHOD("get_visual_spell_effects"), &Spell::get_visual_spell_effects); ClassDB::bind_method(D_METHOD("set_visual_spell_effects", "value"), &Spell::set_visual_spell_effects); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "visual_spell_effects", PROPERTY_HINT_RESOURCE_TYPE, "SpellEffectVisual"), "set_visual_spell_effects", "get_visual_spell_effects"); ClassDB::bind_method(D_METHOD("get_teaches_craft_recipe"), &Spell::get_teaches_craft_recipe); ClassDB::bind_method(D_METHOD("set_teaches_craft_recipe", "value"), &Spell::set_teaches_craft_recipe); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "teaches_craft_recipe", PROPERTY_HINT_RESOURCE_TYPE, "CraftRecipe"), "set_teaches_craft_recipe", "get_teaches_craft_recipe"); ADD_GROUP("Spells Cast", "spells_cast_"); //ADD_GROUP("Caster Aura Applys", "caster_aura_applys"); ClassDB::bind_method(D_METHOD("spells_cast_on_caster_num_get"), &Spell::spells_cast_on_caster_num_get); ClassDB::bind_method(D_METHOD("spells_cast_on_caster_num_set", "value"), &Spell::spells_cast_on_caster_num_set); ClassDB::bind_method(D_METHOD("spell_cast_on_caster_get", "index"), &Spell::spell_cast_on_caster_get); ClassDB::bind_method(D_METHOD("spell_cast_on_caster_set", "index", "spell"), &Spell::spell_cast_on_caster_set); ClassDB::bind_method(D_METHOD("spells_cast_on_caster_get"), &Spell::spells_cast_on_caster_get); ClassDB::bind_method(D_METHOD("spells_cast_on_caster_set", "caster_aura_applys"), &Spell::spells_cast_on_caster_set); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "spells_cast_on_caster", PROPERTY_HINT_NONE, "17/17:Spell", PROPERTY_USAGE_DEFAULT, "Spell"), "spells_cast_on_caster_set", "spells_cast_on_caster_get"); //ADD_GROUP("Target Aura Apply", "target_aura_applys"); ClassDB::bind_method(D_METHOD("spells_cast_on_target_num_get"), &Spell::spells_cast_on_target_num_get); ClassDB::bind_method(D_METHOD("spells_cast_on_target_num_set", "value"), &Spell::spells_cast_on_target_num_set); ClassDB::bind_method(D_METHOD("spell_cast_on_target_get", "index"), &Spell::spell_cast_on_target_get); ClassDB::bind_method(D_METHOD("spell_cast_on_target_set", "index", "spell"), &Spell::spell_cast_on_target_set); ClassDB::bind_method(D_METHOD("spells_cast_on_target_get"), &Spell::spells_cast_on_target_get); ClassDB::bind_method(D_METHOD("spells_cast_on_target_set", "target_aura_applys"), &Spell::spells_cast_on_target_set); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "spells_cast_on_target", PROPERTY_HINT_NONE, "17/17:Spell", PROPERTY_USAGE_DEFAULT, "Spell"), "spells_cast_on_target_set", "spells_cast_on_target_get"); //ADD_GROUP("Apply Auras On Learn", "on_learn_auras"); ClassDB::bind_method(D_METHOD("on_learn_cast_spells_num_get"), &Spell::on_learn_cast_spells_num_get); ClassDB::bind_method(D_METHOD("on_learn_cast_spells_num_set", "value"), &Spell::on_learn_cast_spells_num_set); ClassDB::bind_method(D_METHOD("spell_cast_on_learn_get", "index"), &Spell::spell_cast_on_learn_get); ClassDB::bind_method(D_METHOD("spell_cast_on_learn_set", "index", "spell"), &Spell::spell_cast_on_learn_set); ClassDB::bind_method(D_METHOD("spells_cast_on_learn_get"), &Spell::spells_cast_on_learn_get); ClassDB::bind_method(D_METHOD("spells_cast_on_learn_set", "spells"), &Spell::spells_cast_on_learn_set); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "spells_cast_on_learn", PROPERTY_HINT_NONE, "17/17:Spell", PROPERTY_USAGE_DEFAULT, "Spell"), "spells_cast_on_learn_set", "spells_cast_on_learn_get"); ADD_GROUP("Texts", "text"); //GDVIRTUAL_BIND("_get_description", "class_level", "character_level"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text_name"), "set_name", "get_name"); ClassDB::bind_method(D_METHOD("get_text_translation_key"), &Spell::get_text_translation_key); ClassDB::bind_method(D_METHOD("set_text_translation_key", "value"), &Spell::set_text_description); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text_translation_key"), "set_text_translation_key", "get_text_translation_key"); ClassDB::bind_method(D_METHOD("get_text_description"), &Spell::get_text_description); ClassDB::bind_method(D_METHOD("set_text_description", "value"), &Spell::set_text_description); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text_description", PROPERTY_HINT_MULTILINE_TEXT), "set_text_description", "get_text_description"); ClassDB::bind_method(D_METHOD("get_name_translated"), &Spell::get_name_translated); ClassDB::bind_method(D_METHOD("get_description", "class_level", "character_level"), &Spell::get_description); ClassDB::bind_method(D_METHOD("_get_description", "class_level", "character_level"), &Spell::_get_description); ADD_GROUP("Cooldown", "cooldown"); ClassDB::bind_method(D_METHOD("get_cooldown"), &Spell::get_cooldown); ClassDB::bind_method(D_METHOD("set_cooldown", "value"), &Spell::set_cooldown); ADD_PROPERTY(PropertyInfo(Variant::REAL, "cooldown_cooldown"), "set_cooldown", "get_cooldown"); ClassDB::bind_method(D_METHOD("get_global_cooldown_enabled"), &Spell::get_global_cooldown_enabled); ClassDB::bind_method(D_METHOD("set_global_cooldown_enabled", "value"), &Spell::set_global_cooldown_enabled); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cooldown_global_cooldown_enabled"), "set_global_cooldown_enabled", "get_global_cooldown_enabled"); ADD_GROUP("Range", "range"); ClassDB::bind_method(D_METHOD("range_get_enabled"), &Spell::range_get_enabled); ClassDB::bind_method(D_METHOD("range_set_enabled", "value"), &Spell::range_set_enabled); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "range_enabled"), "range_set_enabled", "range_get_enabled"); ClassDB::bind_method(D_METHOD("range_get"), &Spell::range_get); ClassDB::bind_method(D_METHOD("range_set", "value"), &Spell::range_set); ADD_PROPERTY(PropertyInfo(Variant::REAL, "range_range"), "range_set", "range_get"); ADD_GROUP("Cast", "cast"); ClassDB::bind_method(D_METHOD("cast_time_get_enabled"), &Spell::cast_time_get_enabled); ClassDB::bind_method(D_METHOD("cast_time_set_enabled", "value"), &Spell::cast_time_set_enabled); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cast_enabled"), "cast_time_set_enabled", "cast_time_get_enabled"); ClassDB::bind_method(D_METHOD("cast_time_get"), &Spell::cast_time_get); ClassDB::bind_method(D_METHOD("cast_time_set", "value"), &Spell::cast_time_set); ADD_PROPERTY(PropertyInfo(Variant::REAL, "cast_cast_time"), "cast_time_set", "cast_time_get"); ClassDB::bind_method(D_METHOD("get_can_move_while_casting"), &Spell::get_can_move_while_casting); ClassDB::bind_method(D_METHOD("set_can_move_while_casting", "value"), &Spell::set_can_move_while_casting); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cast_can_move_while_casting"), "set_can_move_while_casting", "get_can_move_while_casting"); ADD_GROUP("Projectile", "projectile"); ClassDB::bind_method(D_METHOD("projectile_get_use_time"), &Spell::projectile_get_use_time); ClassDB::bind_method(D_METHOD("projectile_set_use_time", "value"), &Spell::projectile_set_use_time); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "projectile_use_time"), "projectile_set_use_time", "projectile_get_use_time"); ClassDB::bind_method(D_METHOD("projectile_get_time"), &Spell::projectile_get_time); ClassDB::bind_method(D_METHOD("projectile_set_time", "value"), &Spell::projectile_set_time); ADD_PROPERTY(PropertyInfo(Variant::INT, "projectile_time"), "projectile_set_time", "projectile_get_time"); ClassDB::bind_method(D_METHOD("projectile_get_use_speed"), &Spell::projectile_get_use_speed); ClassDB::bind_method(D_METHOD("projectile_set_use_speed", "value"), &Spell::projectile_set_use_speed); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "projectile_use_speed"), "projectile_set_use_speed", "projectile_get_use_speed"); ClassDB::bind_method(D_METHOD("projectile_get_speed"), &Spell::projectile_get_speed); ClassDB::bind_method(D_METHOD("projectile_set_speed", "value"), &Spell::projectile_set_speed); ADD_PROPERTY(PropertyInfo(Variant::INT, "projectile_speed"), "projectile_set_speed", "projectile_get_speed"); ClassDB::bind_method(D_METHOD("projectile_get_scene"), &Spell::projectile_get_scene); ClassDB::bind_method(D_METHOD("projectile_set_scene", "value"), &Spell::projectile_set_scene); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "projectile_scene", PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"), "projectile_set_scene", "projectile_get_scene"); ADD_GROUP("Damage", "damage"); ClassDB::bind_method(D_METHOD("damage_get_enabled"), &Spell::damage_get_enabled); ClassDB::bind_method(D_METHOD("damage_set_enabled", "value"), &Spell::damage_set_enabled); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "damage_enabled"), "damage_set_enabled", "damage_get_enabled"); ClassDB::bind_method(D_METHOD("damage_get_type"), &Spell::damage_get_type); ClassDB::bind_method(D_METHOD("damage_set_type", "value"), &Spell::damage_set_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "damage_type", PROPERTY_HINT_FLAGS, SpellEnums::BINDING_STRING_DAMAGE_TYPES), "damage_set_type", "damage_get_type"); ClassDB::bind_method(D_METHOD("damage_get_min"), &Spell::damage_get_min); ClassDB::bind_method(D_METHOD("damage_set_min", "value"), &Spell::damage_set_min); ADD_PROPERTY(PropertyInfo(Variant::INT, "damage_min"), "damage_set_min", "damage_get_min"); ClassDB::bind_method(D_METHOD("damage_get_max"), &Spell::damage_get_max); ClassDB::bind_method(D_METHOD("damage_set_max", "value"), &Spell::damage_set_max); ADD_PROPERTY(PropertyInfo(Variant::INT, "damage_max"), "damage_set_max", "damage_get_max"); ClassDB::bind_method(D_METHOD("damage_get_scale_stat"), &Spell::damage_get_scale_stat); ClassDB::bind_method(D_METHOD("damage_set_scale_stat", "value"), &Spell::damage_set_scale_stat); ADD_PROPERTY(PropertyInfo(Variant::INT, "damage_scale_stat", PROPERTY_HINT_ENUM, ""), "damage_set_scale_stat", "damage_get_scale_stat"); ClassDB::bind_method(D_METHOD("damage_get_scale_coeff"), &Spell::damage_get_scale_coeff); ClassDB::bind_method(D_METHOD("damage_set_scale_coeff", "value"), &Spell::damage_set_scale_coeff); ADD_PROPERTY(PropertyInfo(Variant::REAL, "damage_scale_coeff"), "damage_set_scale_coeff", "damage_get_scale_coeff"); ADD_GROUP("Heal", "heal"); ClassDB::bind_method(D_METHOD("heal_get_enabled"), &Spell::heal_get_enabled); ClassDB::bind_method(D_METHOD("heal_set_enabled", "value"), &Spell::heal_set_enabled); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heal_enabled"), "heal_set_enabled", "heal_get_enabled"); ClassDB::bind_method(D_METHOD("heal_get_min"), &Spell::heal_get_min); ClassDB::bind_method(D_METHOD("heal_set_min", "value"), &Spell::heal_set_min); ADD_PROPERTY(PropertyInfo(Variant::INT, "heal_min"), "heal_set_min", "heal_get_min"); ClassDB::bind_method(D_METHOD("heal_get_max"), &Spell::heal_get_max); ClassDB::bind_method(D_METHOD("heal_set_max", "value"), &Spell::heal_set_max); ADD_PROPERTY(PropertyInfo(Variant::INT, "heal_max"), "heal_set_max", "heal_get_max"); ClassDB::bind_method(D_METHOD("heal_get_scale_stat"), &Spell::heal_get_scale_stat); ClassDB::bind_method(D_METHOD("heal_set_scale_stat", "value"), &Spell::heal_set_scale_stat); ADD_PROPERTY(PropertyInfo(Variant::INT, "heal_scale_stat", PROPERTY_HINT_ENUM, ""), "heal_set_scale_stat", "heal_get_scale_stat"); ClassDB::bind_method(D_METHOD("heal_get_scale_coeff"), &Spell::heal_get_scale_coeff); ClassDB::bind_method(D_METHOD("heal_set_scale_coeff", "value"), &Spell::heal_set_scale_coeff); ADD_PROPERTY(PropertyInfo(Variant::REAL, "heal_scale_coeff"), "heal_set_scale_coeff", "heal_get_scale_coeff"); ADD_GROUP("Dispell", "dispell"); ClassDB::bind_method(D_METHOD("dispell_get_enabled"), &Spell::dispell_get_enabled); ClassDB::bind_method(D_METHOD("dispell_set_enabled", "value"), &Spell::dispell_set_enabled); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dispell_enabled"), "dispell_set_enabled", "dispell_get_enabled"); ClassDB::bind_method(D_METHOD("dispell_get_count_min"), &Spell::dispell_get_count_min); ClassDB::bind_method(D_METHOD("dispell_set_count_min", "value"), &Spell::dispell_set_count_min); ADD_PROPERTY(PropertyInfo(Variant::INT, "dispell_count_min"), "dispell_set_count_min", "dispell_get_count_min"); ClassDB::bind_method(D_METHOD("dispell_get_count_max"), &Spell::dispell_get_count_max); ClassDB::bind_method(D_METHOD("dispell_set_count_max", "value"), &Spell::dispell_set_count_max); ADD_PROPERTY(PropertyInfo(Variant::INT, "dispell_count_max"), "dispell_set_count_max", "dispell_get_count_max"); ClassDB::bind_method(D_METHOD("dispell_get_aura_types"), &Spell::dispell_get_aura_types); ClassDB::bind_method(D_METHOD("dispell_set_aura_types", "value"), &Spell::dispell_set_aura_types); ADD_PROPERTY(PropertyInfo(Variant::INT, "dispell_aura_types", PROPERTY_HINT_FLAGS, SpellEnums::BINDING_STRING_AURA_FLAG_TYPES), "dispell_set_aura_types", "dispell_get_aura_types"); ADD_GROUP("Interrupt", "interrupt"); ClassDB::bind_method(D_METHOD("get_interrupt_enabled"), &Spell::get_interrupt_enabled); ClassDB::bind_method(D_METHOD("set_interrupt_enabled", "value"), &Spell::set_interrupt_enabled); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interrupt_enabled"), "set_interrupt_enabled", "get_interrupt_enabled"); ClassDB::bind_method(D_METHOD("get_interrupt_time"), &Spell::get_interrupt_time); ClassDB::bind_method(D_METHOD("set_interrupt_time", "value"), &Spell::set_interrupt_time); ADD_PROPERTY(PropertyInfo(Variant::REAL, "interrupt_time"), "set_interrupt_time", "get_interrupt_time"); ADD_GROUP("Cost", "cost"); ClassDB::bind_method(D_METHOD("get_item_cost"), &Spell::get_item_cost); ClassDB::bind_method(D_METHOD("set_item_cost", "value"), &Spell::set_item_cost); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "cost_item", PROPERTY_HINT_RESOURCE_TYPE, "ItemTemplate"), "set_item_cost", "get_item_cost"); ClassDB::bind_method(D_METHOD("get_required_item"), &Spell::get_required_item); ClassDB::bind_method(D_METHOD("set_required_item", "value"), &Spell::set_required_item); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "cost_required_item", PROPERTY_HINT_RESOURCE_TYPE, "ItemTemplate"), "set_required_item", "get_required_item"); ADD_GROUP("Resources", "resource"); ClassDB::bind_method(D_METHOD("get_resource_cost"), &Spell::get_resource_cost); ClassDB::bind_method(D_METHOD("set_resource_cost", "value"), &Spell::set_resource_cost); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "resource_cost", PROPERTY_HINT_RESOURCE_TYPE, "EntityResourceCostData"), "set_resource_cost", "get_resource_cost"); ClassDB::bind_method(D_METHOD("get_resource_give"), &Spell::get_resource_give); ClassDB::bind_method(D_METHOD("set_resource_give", "value"), &Spell::set_resource_give); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "resource_give", PROPERTY_HINT_RESOURCE_TYPE, "EntityResourceCostData"), "set_resource_give", "get_resource_give"); ADD_GROUP("AOE", "aoe"); ClassDB::bind_method(D_METHOD("get_is_aoe"), &Spell::get_is_aoe); ClassDB::bind_method(D_METHOD("set_is_aoe", "value"), &Spell::set_is_aoe); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "aoe"), "set_is_aoe", "get_is_aoe"); ClassDB::bind_method(D_METHOD("get_aoe_target_type"), &Spell::get_aoe_target_type); ClassDB::bind_method(D_METHOD("set_aoe_target_type", "value"), &Spell::set_aoe_target_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "aoe_targetType", PROPERTY_HINT_ENUM, "Caster, Target, Ground Target Selection, Random"), "set_aoe_target_type", "get_aoe_target_type"); ClassDB::bind_method(D_METHOD("get_aoe_collider_type"), &Spell::get_aoe_collider_type); ClassDB::bind_method(D_METHOD("set_aoe_collider_type", "value"), &Spell::set_aoe_collider_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "aoe_colliderType", PROPERTY_HINT_ENUM, SpellEnums::BINDING_STRING_COLLIDER_TYPE), "set_aoe_collider_type", "get_aoe_collider_type"); ClassDB::bind_method(D_METHOD("get_aoe_radius"), &Spell::get_aoe_radius); ClassDB::bind_method(D_METHOD("set_aoe_radius", "value"), &Spell::set_aoe_radius); ADD_PROPERTY(PropertyInfo(Variant::REAL, "aoe_radius"), "set_aoe_radius", "get_aoe_radius"); ClassDB::bind_method(D_METHOD("get_aoe_box_extents"), &Spell::get_aoe_box_extents); ClassDB::bind_method(D_METHOD("set_aoe_box_extents", "value"), &Spell::set_aoe_box_extents); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "aoe_box_extents"), "set_aoe_box_extents", "get_aoe_box_extents"); ADD_GROUP("Spell Cooldown Mainpulation", "spell_cooldown_mainpulation"); ClassDB::bind_method(D_METHOD("get_spell_cooldown_mainpulation_data_count"), &Spell::get_spell_cooldown_mainpulation_data_count); ClassDB::bind_method(D_METHOD("set_spell_cooldown_mainpulation_data_count", "value"), &Spell::set_spell_cooldown_mainpulation_data_count); ADD_PROPERTY(PropertyInfo(Variant::INT, "spell_cooldown_mainpulation_data_count"), "set_spell_cooldown_mainpulation_data_count", "get_spell_cooldown_mainpulation_data_count"); ADD_GROUP("Training", "training"); ClassDB::bind_method(D_METHOD("get_training_cost"), &Spell::get_training_cost); ClassDB::bind_method(D_METHOD("set_training_cost", "value"), &Spell::set_training_cost); ADD_PROPERTY(PropertyInfo(Variant::INT, "training_cost"), "set_training_cost", "get_training_cost"); ClassDB::bind_method(D_METHOD("get_training_required_spell"), &Spell::get_training_required_spell); ClassDB::bind_method(D_METHOD("set_training_required_spell", "curspellve"), &Spell::set_training_required_spell); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "training_required_spell", PROPERTY_HINT_RESOURCE_TYPE, "Spell"), "set_training_required_spell", "get_training_required_spell"); ClassDB::bind_method(D_METHOD("get_training_required_skill"), &Spell::get_training_required_skill); ClassDB::bind_method(D_METHOD("set_training_required_skill", "curve"), &Spell::set_training_required_skill); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "training_required_skill", PROPERTY_HINT_RESOURCE_TYPE, "EntitySkillData"), "set_training_required_skill", "get_training_required_skill"); ClassDB::bind_method(D_METHOD("get_training_required_skill_level"), &Spell::get_training_required_skill_level); ClassDB::bind_method(D_METHOD("set_training_required_skill_level", "value"), &Spell::set_training_required_skill_level); ADD_PROPERTY(PropertyInfo(Variant::INT, "training_required_skill_level"), "set_training_required_skill_level", "get_training_required_skill_level"); ADD_GROUP("Aura", "aura"); ClassDB::bind_method(D_METHOD("aura_get_permanent"), &Spell::aura_get_permanent); ClassDB::bind_method(D_METHOD("aura_set_permanent", "value"), &Spell::aura_set_permanent); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "aura_permanent"), "aura_set_permanent", "aura_get_permanent"); ClassDB::bind_method(D_METHOD("aura_get_time"), &Spell::aura_get_time); ClassDB::bind_method(D_METHOD("aura_set_time", "value"), &Spell::aura_set_time); ADD_PROPERTY(PropertyInfo(Variant::REAL, "aura_time"), "aura_set_time", "aura_get_time"); ClassDB::bind_method(D_METHOD("aura_get_tick"), &Spell::aura_get_tick); ClassDB::bind_method(D_METHOD("aura_set_tick", "value"), &Spell::aura_set_tick); ADD_PROPERTY(PropertyInfo(Variant::REAL, "aura_tick"), "aura_set_tick", "aura_get_tick"); ClassDB::bind_method(D_METHOD("aura_get_is_debuff"), &Spell::aura_get_is_debuff); ClassDB::bind_method(D_METHOD("aura_set_is_debuff", "value"), &Spell::aura_set_is_debuff); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "aura_debuff"), "aura_set_is_debuff", "aura_get_is_debuff"); ClassDB::bind_method(D_METHOD("aura_get_scale_with_level"), &Spell::aura_get_scale_with_level); ClassDB::bind_method(D_METHOD("aura_set_scale_with_level", "value"), &Spell::aura_set_scale_with_level); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "aura_scale_with_level"), "aura_set_scale_with_level", "aura_get_scale_with_level"); ClassDB::bind_method(D_METHOD("aura_get_aura_type"), &Spell::aura_get_aura_type); ClassDB::bind_method(D_METHOD("aura_set_aura_type", "value"), &Spell::aura_set_aura_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_type", PROPERTY_HINT_ENUM, SpellEnums::BINDING_STRING_AURA_TYPES), "aura_set_aura_type", "aura_get_aura_type"); ClassDB::bind_method(D_METHOD("aura_get_aura_group"), &Spell::aura_get_aura_group); ClassDB::bind_method(D_METHOD("aura_set_aura_group", "value"), &Spell::aura_set_aura_group); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "aura_group", PROPERTY_HINT_RESOURCE_TYPE, "AuraGroup"), "aura_set_aura_group", "aura_get_aura_group"); ClassDB::bind_method(D_METHOD("aura_get_hide"), &Spell::aura_get_hide); ClassDB::bind_method(D_METHOD("aura_set_hide", "value"), &Spell::aura_set_hide); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "aura_hide"), "aura_set_hide", "aura_get_hide"); ClassDB::bind_method(D_METHOD("aura_get_ability_scale_data_id"), &Spell::aura_get_ability_scale_data_id); ClassDB::bind_method(D_METHOD("aura_set_ability_scale_data_id", "value"), &Spell::aura_set_ability_scale_data_id); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_ability_scale_data_id"), "aura_set_ability_scale_data_id", "aura_get_ability_scale_data_id"); ClassDB::bind_method(D_METHOD("aura_get_visual_spell_effects"), &Spell::aura_get_visual_spell_effects); ClassDB::bind_method(D_METHOD("aura_set_visual_spell_effects", "value"), &Spell::aura_set_visual_spell_effects); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "aura_visual_spell_effects", PROPERTY_HINT_RESOURCE_TYPE, "SpellEffectVisual"), "aura_set_visual_spell_effects", "aura_get_visual_spell_effects"); //GDVIRTUAL_BIND("_aura_get_description", "class_level", "character_level"); ADD_GROUP("Aura Texts", "aura_text"); ClassDB::bind_method(D_METHOD("aura_get_text_translation_key"), &Spell::aura_get_text_translation_key); ClassDB::bind_method(D_METHOD("aura_set_text_translation_key", "value"), &Spell::aura_set_text_translation_key); ADD_PROPERTY(PropertyInfo(Variant::STRING, "aura_text_translation_key"), "aura_set_text_translation_key", "aura_get_text_translation_key"); ClassDB::bind_method(D_METHOD("aura_get_text_description"), &Spell::aura_get_text_description); ClassDB::bind_method(D_METHOD("aura_set_text_description", "value"), &Spell::aura_set_text_description); ADD_PROPERTY(PropertyInfo(Variant::STRING, "aura_text_description", PROPERTY_HINT_MULTILINE_TEXT), "aura_set_text_description", "aura_get_text_description"); ClassDB::bind_method(D_METHOD("aura_get_name_translated"), &Spell::aura_get_name_translated); ClassDB::bind_method(D_METHOD("aura_get_description", "class_level", "character_level"), &Spell::aura_get_description); ClassDB::bind_method(D_METHOD("_aura_get_description", "class_level", "character_level"), &Spell::_aura_get_description); ADD_GROUP("Aura Damage", "aura_damage"); //Damage ClassDB::bind_method(D_METHOD("aura_damage_get_enabled"), &Spell::aura_damage_get_enabled); ClassDB::bind_method(D_METHOD("aura_damage_set_enabled", "value"), &Spell::aura_damage_set_enabled); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "aura_damage_enabled"), "aura_damage_set_enabled", "aura_damage_get_enabled"); ClassDB::bind_method(D_METHOD("aura_damage_get_type"), &Spell::aura_damage_get_type); ClassDB::bind_method(D_METHOD("aura_damage_set_type", "value"), &Spell::aura_damage_set_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_damage_type", PROPERTY_HINT_FLAGS, SpellEnums::BINDING_STRING_DAMAGE_TYPES), "aura_damage_set_type", "aura_damage_get_type"); ClassDB::bind_method(D_METHOD("aura_damage_get_min"), &Spell::aura_damage_get_min); ClassDB::bind_method(D_METHOD("aura_damage_set_min", "value"), &Spell::aura_damage_set_min); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_damage_min"), "aura_damage_set_min", "aura_damage_get_min"); ClassDB::bind_method(D_METHOD("aura_damage_get_max"), &Spell::aura_damage_get_max); ClassDB::bind_method(D_METHOD("aura_damage_set_max", "value"), &Spell::aura_damage_set_max); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_damage_max"), "aura_damage_set_max", "aura_damage_get_max"); ClassDB::bind_method(D_METHOD("aura_damage_get_can_crit"), &Spell::aura_damage_get_can_crit); ClassDB::bind_method(D_METHOD("aura_damage_set_can_crit", "value"), &Spell::aura_damage_set_can_crit); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "aura_damage_can_crit"), "aura_damage_set_can_crit", "aura_damage_get_can_crit"); ClassDB::bind_method(D_METHOD("aura_damage_set", "min", "max", "can_crit"), &Spell::aura_damage_set); ClassDB::bind_method(D_METHOD("aura_damage_get_scaling_curve"), &Spell::aura_damage_get_scaling_curve); ClassDB::bind_method(D_METHOD("aura_damage_set_scaling_curve", "curve"), &Spell::aura_damage_set_scaling_curve); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "aura_damage_scaling_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "aura_damage_set_scaling_curve", "aura_damage_get_scaling_curve"); ADD_GROUP("Aura Absorb", "aura_absorb"); //Absorb ClassDB::bind_method(D_METHOD("aura_absorb_get_enabled"), &Spell::aura_absorb_get_enabled); ClassDB::bind_method(D_METHOD("aura_absorb_set_enabled", "value"), &Spell::aura_absorb_set_enabled); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "aura_absorb_enabled"), "aura_absorb_set_enabled", "aura_absorb_get_enabled"); ClassDB::bind_method(D_METHOD("aura_absorb_damage_get_type"), &Spell::aura_absorb_damage_get_type); ClassDB::bind_method(D_METHOD("aura_absorb_damage_set_type", "value"), &Spell::aura_absorb_damage_set_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_absorb_damage_type", PROPERTY_HINT_FLAGS, SpellEnums::BINDING_STRING_DAMAGE_TYPES), "aura_absorb_damage_set_type", "aura_absorb_damage_get_type"); ClassDB::bind_method(D_METHOD("aura_absorb_get_min"), &Spell::aura_absorb_get_min); ClassDB::bind_method(D_METHOD("aura_absorb_set_min", "value"), &Spell::aura_absorb_set_min); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_absorb_min"), "aura_absorb_set_min", "aura_absorb_get_min"); ClassDB::bind_method(D_METHOD("aura_absorb_get_max"), &Spell::aura_absorb_get_max); ClassDB::bind_method(D_METHOD("aura_absorb_set_max", "value"), &Spell::aura_absorb_set_max); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_absorb_max"), "aura_absorb_set_max", "aura_absorb_get_max"); ClassDB::bind_method(D_METHOD("aura_absorb_get_scaling_curve"), &Spell::aura_absorb_get_scaling_curve); ClassDB::bind_method(D_METHOD("aura_absorb_set_scaling_curve", "curve"), &Spell::aura_absorb_set_scaling_curve); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "aura_absorb_scaling_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "aura_absorb_set_scaling_curve", "aura_absorb_get_scaling_curve"); ADD_GROUP("Aura Heal", "aura_heal"); //Heal ClassDB::bind_method(D_METHOD("aura_heal_get_enabled"), &Spell::aura_heal_get_enabled); ClassDB::bind_method(D_METHOD("aura_heal_set_enabled", "value"), &Spell::aura_heal_set_enabled); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "aura_heal_enabled"), "aura_heal_set_enabled", "aura_heal_get_enabled"); ClassDB::bind_method(D_METHOD("aura_heal_get_min"), &Spell::aura_heal_get_min); ClassDB::bind_method(D_METHOD("aura_heal_set_min", "value"), &Spell::aura_heal_set_min); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_heal_min"), "aura_heal_set_min", "aura_heal_get_min"); ClassDB::bind_method(D_METHOD("aura_heal_get_max"), &Spell::aura_heal_get_max); ClassDB::bind_method(D_METHOD("aura_heal_set_max", "value"), &Spell::aura_heal_set_max); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_heal_max"), "aura_heal_set_max", "aura_heal_get_max"); ClassDB::bind_method(D_METHOD("aura_heal_get_can_crit"), &Spell::aura_heal_get_can_crit); ClassDB::bind_method(D_METHOD("aura_heal_set_can_crit", "value"), &Spell::aura_heal_set_can_crit); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "aura_heal_can_crit"), "aura_heal_set_can_crit", "aura_heal_get_can_crit"); ClassDB::bind_method(D_METHOD("aura_heal_set", "min", "max", "can_crit"), &Spell::aura_heal_set); ClassDB::bind_method(D_METHOD("aura_heal_get_scaling_curve"), &Spell::aura_heal_get_scaling_curve); ClassDB::bind_method(D_METHOD("aura_heal_set_scaling_curve", "curve"), &Spell::aura_heal_set_scaling_curve); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "aura_heal_scaling_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "aura_heal_set_scaling_curve", "aura_heal_get_scaling_curve"); ADD_GROUP("Aura Dispell", "aura_dispell"); ClassDB::bind_method(D_METHOD("aura_dispell_get_enabled"), &Spell::aura_dispell_get_enabled); ClassDB::bind_method(D_METHOD("aura_dispell_set_enabled", "value"), &Spell::aura_dispell_set_enabled); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "aura_dispell_enabled"), "aura_dispell_set_enabled", "aura_dispell_get_enabled"); ClassDB::bind_method(D_METHOD("aura_dispell_get_count_min"), &Spell::aura_dispell_get_count_min); ClassDB::bind_method(D_METHOD("aura_dispell_set_count_min", "value"), &Spell::aura_dispell_set_count_min); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_dispell_count_min"), "aura_dispell_set_count_min", "aura_dispell_get_count_min"); ClassDB::bind_method(D_METHOD("aura_dispell_get_count_max"), &Spell::aura_dispell_get_count_max); ClassDB::bind_method(D_METHOD("aura_dispell_set_count_max", "value"), &Spell::aura_dispell_set_count_max); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_dispell_count_max"), "aura_dispell_set_count_max", "aura_dispell_get_count_max"); ClassDB::bind_method(D_METHOD("aura_dispell_get_aura_types"), &Spell::aura_dispell_get_aura_types); ClassDB::bind_method(D_METHOD("aura_dispell_set_aura_types", "value"), &Spell::aura_dispell_set_aura_types); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_dispell_aura_types", PROPERTY_HINT_FLAGS, SpellEnums::BINDING_STRING_AURA_FLAG_TYPES), "aura_dispell_set_aura_types", "aura_dispell_get_aura_types"); //Resources ADD_GROUP("Aura Resources", "aura_resource"); ClassDB::bind_method(D_METHOD("aura_get_resource_cost"), &Spell::aura_get_resource_cost); ClassDB::bind_method(D_METHOD("aura_set_resource_cost", "value"), &Spell::aura_set_resource_cost); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "aura_resource_cost", PROPERTY_HINT_RESOURCE_TYPE, "EntityResourceCostData"), "aura_set_resource_cost", "aura_get_resource_cost"); ClassDB::bind_method(D_METHOD("aura_get_resource_give"), &Spell::aura_get_resource_give); ClassDB::bind_method(D_METHOD("aura_set_resource_give", "value"), &Spell::aura_set_resource_give); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "aura_resource_give", PROPERTY_HINT_RESOURCE_TYPE, "EntityResourceCostData"), "aura_set_resource_give", "aura_get_resource_give"); ADD_GROUP("Aura States", "aura_states"); ClassDB::bind_method(D_METHOD("aura_get_add_states"), &Spell::aura_get_add_states); ClassDB::bind_method(D_METHOD("aura_set_add_states", "value"), &Spell::aura_set_add_states); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_states_add", PROPERTY_HINT_FLAGS, EntityEnums::BINDING_STRING_ENTITY_STATE_TYPES), "aura_set_add_states", "aura_get_add_states"); ClassDB::bind_method(D_METHOD("aura_get_remove_effects_with_states"), &Spell::aura_get_remove_effects_with_states); ClassDB::bind_method(D_METHOD("aura_set_remove_effects_with_states", "value"), &Spell::aura_set_remove_effects_with_states); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_states_remove_effects", PROPERTY_HINT_FLAGS, EntityEnums::BINDING_STRING_ENTITY_STATE_TYPES), "aura_set_remove_effects_with_states", "aura_get_remove_effects_with_states"); ClassDB::bind_method(D_METHOD("aura_get_supress_states"), &Spell::aura_get_supress_states); ClassDB::bind_method(D_METHOD("aura_set_supress_states", "value"), &Spell::aura_set_supress_states); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_states_supress", PROPERTY_HINT_FLAGS, EntityEnums::BINDING_STRING_ENTITY_STATE_TYPES), "aura_set_supress_states", "aura_get_supress_states"); //Diminishing Returns ADD_GROUP("Aura Diminishing Returns", "aura_diminishing_return"); ClassDB::bind_method(D_METHOD("aura_diminishing_return_enabled_get"), &Spell::aura_diminishing_return_enabled_get); ClassDB::bind_method(D_METHOD("aura_diminishing_return_enabled_set", "value"), &Spell::aura_diminishing_return_enabled_set); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "aura_diminishing_return_enabled"), "aura_diminishing_return_enabled_set", "aura_diminishing_return_enabled_get"); ClassDB::bind_method(D_METHOD("aura_diminishing_return_category_get"), &Spell::aura_diminishing_return_category_get); ClassDB::bind_method(D_METHOD("aura_diminishing_return_category_set", "value"), &Spell::aura_diminishing_return_category_set); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_diminishing_return_category", PROPERTY_HINT_ENUM, ""), "aura_diminishing_return_category_set", "aura_diminishing_return_category_get"); //// Talents //// ADD_GROUP("Aura Talent", "aura_talent"); ClassDB::bind_method(D_METHOD("aura_get_talent_required_talent"), &Spell::aura_get_talent_required_talent); ClassDB::bind_method(D_METHOD("aura_set_talent_required_talent", "next_rank"), &Spell::aura_set_talent_required_talent); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "aura_talent_required_talent", PROPERTY_HINT_RESOURCE_TYPE, "Spell"), "aura_set_talent_required_talent", "aura_get_talent_required_talent"); ClassDB::bind_method(D_METHOD("aura_get_talent_required_spell"), &Spell::aura_get_talent_required_spell); ClassDB::bind_method(D_METHOD("aura_set_talent_required_spell", "next_rank"), &Spell::aura_set_talent_required_spell); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "aura_talent_required_spell", PROPERTY_HINT_RESOURCE_TYPE, "Spell"), "aura_set_talent_required_spell", "aura_get_talent_required_spell"); ADD_GROUP("Aura Teaches", "aura_teaches"); ClassDB::bind_method(D_METHOD("aura_get_teaches_spell"), &Spell::aura_get_teaches_spell); ClassDB::bind_method(D_METHOD("aura_set_teaches_spell", "next_rank"), &Spell::aura_set_teaches_spell); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "aura_teaches_spell", PROPERTY_HINT_RESOURCE_TYPE, "Spell"), "aura_set_teaches_spell", "aura_get_teaches_spell"); //// Triggers //// ADD_GROUP("Aura Triggers", "aura_trigger"); ClassDB::bind_method(D_METHOD("aura_trigger_get_count"), &Spell::aura_trigger_get_count); ClassDB::bind_method(D_METHOD("aura_trigger_set_count", "count"), &Spell::aura_trigger_set_count); ClassDB::bind_method(D_METHOD("aura_trigger_get_notification_type", "index"), &Spell::aura_trigger_get_notification_type); ClassDB::bind_method(D_METHOD("aura_trigger_set_notification_type", "index", "value"), &Spell::aura_trigger_set_notification_type); ClassDB::bind_method(D_METHOD("aura_trigger_get_notification_data", "index"), &Spell::aura_trigger_get_notification_data); ClassDB::bind_method(D_METHOD("aura_trigger_set_notification_data", "index", "value"), &Spell::aura_trigger_set_notification_data); ClassDB::bind_method(D_METHOD("aura_trigger_get_trigger_type", "index"), &Spell::aura_trigger_get_trigger_type); ClassDB::bind_method(D_METHOD("aura_trigger_set_trigger_type", "index", "value"), &Spell::aura_trigger_set_trigger_type); ClassDB::bind_method(D_METHOD("aura_trigger_get_trigger_type_data", "index"), &Spell::aura_trigger_get_trigger_type_data); ClassDB::bind_method(D_METHOD("aura_trigger_set_trigger_type_data", "index", "value"), &Spell::aura_trigger_set_trigger_type_data); ClassDB::bind_method(D_METHOD("aura_trigger_get_spell", "index"), &Spell::aura_trigger_get_spell); ClassDB::bind_method(D_METHOD("aura_trigger_set_spell", "index", "value"), &Spell::aura_trigger_set_spell); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_trigger_count", PROPERTY_HINT_RANGE, "0," + itos(MAX_TRIGGER_DATA), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "aura_trigger_set_count", "aura_trigger_get_count"); for (int i = 0; i < MAX_TRIGGER_DATA; i++) { ADD_PROPERTYI(PropertyInfo(Variant::INT, "aura_trigger_" + itos(i) + "/notification_type", PROPERTY_HINT_ENUM, SpellEnums::BINDING_STRING_TRIGGER_NOTIFICATION_TYPE, PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "aura_trigger_set_notification_type", "aura_trigger_get_notification_type", i); ADD_PROPERTYI(PropertyInfo(Variant::INT, "aura_trigger_" + itos(i) + "/notification_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "aura_trigger_set_notification_data", "aura_trigger_get_notification_data", i); ADD_PROPERTYI(PropertyInfo(Variant::INT, "aura_trigger_" + itos(i) + "/trigger_type", PROPERTY_HINT_ENUM, SpellEnums::BINDING_STRING_TRIGGER_TYPE, PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "aura_trigger_set_trigger_type", "aura_trigger_get_trigger_type", i); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "aura_trigger_" + itos(i) + "/trigger_type_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "aura_trigger_set_trigger_type_data", "aura_trigger_get_trigger_type_data", i); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "aura_trigger_" + itos(i) + "/spell", PROPERTY_HINT_RESOURCE_TYPE, "Spell", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "aura_trigger_set_spell", "aura_trigger_get_spell", i); } ADD_GROUP("Aura Stat Attributes", "aura_stat_attribute"); //AuraStatAttributes ClassDB::bind_method(D_METHOD("aura_stat_attribute_get_count"), &Spell::aura_stat_attribute_get_count); ClassDB::bind_method(D_METHOD("aura_stat_attribute_set_count", "count"), &Spell::aura_stat_attribute_set_count); ClassDB::bind_method(D_METHOD("aura_stat_attribute_get_stat", "index"), &Spell::aura_stat_attribute_get_stat); ClassDB::bind_method(D_METHOD("aura_stat_attribute_set_stat", "index", "value"), &Spell::aura_stat_attribute_set_stat); ClassDB::bind_method(D_METHOD("aura_stat_attribute_get_base_mod", "index"), &Spell::aura_stat_attribute_get_base_mod); ClassDB::bind_method(D_METHOD("aura_stat_attribute_set_base_mod", "index", "value"), &Spell::aura_stat_attribute_set_base_mod); ClassDB::bind_method(D_METHOD("aura_stat_attribute_get_bonus_mod", "index"), &Spell::aura_stat_attribute_get_bonus_mod); ClassDB::bind_method(D_METHOD("aura_stat_attribute_set_bonus_mod", "index", "value"), &Spell::aura_stat_attribute_set_bonus_mod); ClassDB::bind_method(D_METHOD("aura_stat_attribute_get_percent_mod", "index"), &Spell::aura_stat_attribute_get_percent_mod); ClassDB::bind_method(D_METHOD("aura_stat_attribute_set_percent_mod", "index", "value"), &Spell::aura_stat_attribute_set_percent_mod); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_stat_attribute_count", PROPERTY_HINT_RANGE, "0," + itos(MAX_AURA_STATS), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "aura_stat_attribute_set_count", "aura_stat_attribute_get_count"); for (int i = 0; i < MAX_AURA_STATS; i++) { ADD_PROPERTYI(PropertyInfo(Variant::INT, "aura_stat_attribute_" + itos(i) + "/stat", PROPERTY_HINT_ENUM, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "aura_stat_attribute_set_stat", "aura_stat_attribute_get_stat", i); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "aura_stat_attribute_" + itos(i) + "/base_mod", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "aura_stat_attribute_set_base_mod", "aura_stat_attribute_get_base_mod", i); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "aura_stat_attribute_" + itos(i) + "/bonus_mod", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "aura_stat_attribute_set_bonus_mod", "aura_stat_attribute_get_bonus_mod", i); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "aura_stat_attribute_" + itos(i) + "/percent_mod", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "aura_stat_attribute_set_percent_mod", "aura_stat_attribute_get_percent_mod", i); } ClassDB::bind_method(D_METHOD("is_aura"), &Spell::is_aura); ClassDB::bind_method(D_METHOD("aura_is_talent"), &Spell::aura_is_talent); BIND_ENUM_CONSTANT(TARGET_SELF); BIND_ENUM_CONSTANT(TARGET_ENEMY); BIND_ENUM_CONSTANT(TARGET_FRIENDLY); BIND_ENUM_CONSTANT(SPELL_TARGET_TYPE_SELF); BIND_ENUM_CONSTANT(SPELL_TARGET_TYPE_TARGET); BIND_ENUM_CONSTANT(SPELL_TARGET_TYPE_AROUND); BIND_ENUM_CONSTANT(SPELL_TARGET_TYPE_FRONT); BIND_ENUM_CONSTANT(SPELL_TARGET_TYPE_AROUND_TARGET); BIND_ENUM_CONSTANT(SPELL_AOE_TARGET_TYPE_CASTER); BIND_ENUM_CONSTANT(SPELL_AOE_TARGET_TYPE_TARGET); BIND_ENUM_CONSTANT(SPELL_AOE_TARGET_TYPE_GOUND_TARGET_SELECTION); BIND_ENUM_CONSTANT(SPELL_AOE_TARGET_TYPE_RANDOM); BIND_CONSTANT(MAX_AURA_STATS); BIND_CONSTANT(MAX_TRIGGER_DATA); } ================================================ FILE: data/spells/spell.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef SPELL_H #define SPELL_H #include "core/version.h" #include "core/io/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; enum TargetRelationType { TARGET_SELF = 1 << 0, TARGET_ENEMY = 1 << 1, TARGET_FRIENDLY = 1 << 2 }; VARIANT_ENUM_CAST(TargetRelationType); enum SpellTargetType { SPELL_TARGET_TYPE_SELF, SPELL_TARGET_TYPE_TARGET, SPELL_TARGET_TYPE_AROUND, SPELL_TARGET_TYPE_FRONT, SPELL_TARGET_TYPE_AROUND_TARGET }; VARIANT_ENUM_CAST(SpellTargetType); enum SpellAOETargetType { SPELL_AOE_TARGET_TYPE_CASTER, SPELL_AOE_TARGET_TYPE_TARGET, SPELL_AOE_TARGET_TYPE_GOUND_TARGET_SELECTION, SPELL_AOE_TARGET_TYPE_RANDOM }; VARIANT_ENUM_CAST(SpellAOETargetType); class Spell : public Resource { GDCLASS(Spell, Resource); 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; }; #endif ================================================ FILE: data/spells/spell_cooldown_manipulation_data.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "spell_cooldown_manipulation_data.h" ================================================ FILE: data/spells/spell_cooldown_manipulation_data.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef SPELL_COOLDOWN_MANIPULATION_DATA_H #define SPELL_COOLDOWN_MANIPULATION_DATA_H #include "core/version.h" #include "core/io/resource.h" class SpellCooldownManipulationData : public RefCounted { GDCLASS(SpellCooldownManipulationData, RefCounted); public: void set_id() {} SpellCooldownManipulationData() { _spell_id = 0; _mod_value = 0; _remove_if_exists = false; _add_if_not_exists = false; } protected: static void _bind_methods() { } private: int _spell_id; int _mod_value; bool _remove_if_exists; bool _add_if_not_exists; }; #endif ================================================ FILE: data/spells/spell_effect_visual.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "spell_effect_visual.h" SpellEffectVisual::SpellEffectVisual() { } SpellEffectVisual::~SpellEffectVisual() { } void SpellEffectVisual::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "text_name"), "set_name", "get_name"); } ================================================ FILE: data/spells/spell_effect_visual.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef SPELL_EFFECT_VISUAL_H #define SPELL_EFFECT_VISUAL_H #include "core/version.h" #include "core/io/resource.h" class SpellEffectVisual : public Resource { GDCLASS(SpellEffectVisual, Resource); public: SpellEffectVisual(); ~SpellEffectVisual(); protected: static void _bind_methods(); private: }; #endif ================================================ FILE: data/spells/spell_effect_visual_simple.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "spell_effect_visual_simple.h" bool SpellEffectVisualSimple::has_spell_effect_visual() { return _effect_visual.is_valid(); } EntityEnums::CommonCharacterSkeletonPoints SpellEffectVisualSimple::get_spell_effect_visual_point() { return _effect_visual_point; } void SpellEffectVisualSimple::set_spell_effect_visual_point(EntityEnums::CommonCharacterSkeletonPoints point) { _effect_visual_point = point; } Ref SpellEffectVisualSimple::get_spell_effect_visual() { return _effect_visual; } void SpellEffectVisualSimple::set_spell_effect_visual(Ref value) { _effect_visual = value; } bool SpellEffectVisualSimple::has_spell_cast_finish_effect() { return _spell_cast_finish_effect.is_valid(); } EntityEnums::CommonCharacterSkeletonPoints SpellEffectVisualSimple::get_spell_cast_finish_effect_point() { return _spell_cast_finish_effect_point; } void SpellEffectVisualSimple::set_spell_cast_finish_effect_point(EntityEnums::CommonCharacterSkeletonPoints point) { _spell_cast_finish_effect_point = point; } Ref SpellEffectVisualSimple::get_spell_cast_finish_effect() { return _spell_cast_finish_effect; } void SpellEffectVisualSimple::set_spell_cast_finish_effect(Ref value) { _spell_cast_finish_effect = value; } bool SpellEffectVisualSimple::has_spell_cast_effect() { return _spell_cast_effect.is_valid(); } Ref SpellEffectVisualSimple::get_spell_cast_effect() { return _spell_cast_effect; } void SpellEffectVisualSimple::set_spell_cast_effect(Ref value) { _spell_cast_effect = value; } //Visual Effect bool SpellEffectVisualSimple::has_aura_effect_visual() { return _effect_visual.is_valid(); } EntityEnums::CommonCharacterSkeletonPoints SpellEffectVisualSimple::get_aura_effect_visual_point() { return _aura_effect_visual_point; } void SpellEffectVisualSimple::set_aura_effect_visual_point(EntityEnums::CommonCharacterSkeletonPoints point) { _aura_effect_visual_point = point; } Ref SpellEffectVisualSimple::get_aura_effect_visual() { return _aura_effect_visual; } void SpellEffectVisualSimple::set_aura_effect_visual(Ref value) { _aura_effect_visual = value; } SpellEffectVisualSimple::SpellEffectVisualSimple() { } SpellEffectVisualSimple::~SpellEffectVisualSimple() { } void SpellEffectVisualSimple::_bind_methods() { ADD_GROUP("Effect", "spell_effect"); ClassDB::bind_method(D_METHOD("has_spell_effect_visual"), &SpellEffectVisualSimple::has_spell_effect_visual); ClassDB::bind_method(D_METHOD("get_spell_effect_visual_point"), &SpellEffectVisualSimple::get_spell_effect_visual_point); ClassDB::bind_method(D_METHOD("set_spell_effect_visual_point", "value"), &SpellEffectVisualSimple::set_spell_effect_visual_point); ADD_PROPERTY(PropertyInfo(Variant::INT, "spell_effect_visual_point", PROPERTY_HINT_ENUM, EntityEnums::BINDING_STRING_COMMON_CHARCATER_SKELETON_POINTS), "set_spell_effect_visual_point", "get_spell_effect_visual_point"); ClassDB::bind_method(D_METHOD("get_spell_effect_visual"), &SpellEffectVisualSimple::get_spell_effect_visual); ClassDB::bind_method(D_METHOD("set_spell_effect_visual", "value"), &SpellEffectVisualSimple::set_spell_effect_visual); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "spell_effect_visual", PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"), "set_spell_effect_visual", "get_spell_effect_visual"); ClassDB::bind_method(D_METHOD("has_spell_spell_cast_finish_effect"), &SpellEffectVisualSimple::has_spell_cast_finish_effect); ClassDB::bind_method(D_METHOD("get_spell_cast_finish_effect_point"), &SpellEffectVisualSimple::get_spell_cast_finish_effect_point); ClassDB::bind_method(D_METHOD("set_spell_cast_finish_effect_point", "value"), &SpellEffectVisualSimple::set_spell_cast_finish_effect_point); ADD_PROPERTY(PropertyInfo(Variant::INT, "spell_cast_finish_effect_point", PROPERTY_HINT_ENUM, EntityEnums::BINDING_STRING_COMMON_CHARCATER_SKELETON_POINTS), "set_spell_cast_finish_effect_point", "get_spell_cast_finish_effect_point"); ClassDB::bind_method(D_METHOD("get_spell_cast_finish_effect"), &SpellEffectVisualSimple::get_spell_cast_finish_effect); ClassDB::bind_method(D_METHOD("set_spell_cast_finish_effect", "value"), &SpellEffectVisualSimple::set_spell_cast_finish_effect); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "effect_spell_cast_finish_effect", PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"), "set_spell_cast_finish_effect", "get_spell_cast_finish_effect"); ClassDB::bind_method(D_METHOD("has_spell_cast_effect"), &SpellEffectVisualSimple::has_spell_cast_effect); ClassDB::bind_method(D_METHOD("get_spell_cast_effect"), &SpellEffectVisualSimple::get_spell_cast_effect); ClassDB::bind_method(D_METHOD("set_spell_cast_effect", "value"), &SpellEffectVisualSimple::set_spell_cast_effect); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "effect_spell_cast_effect_id", PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"), "set_spell_cast_effect", "get_spell_cast_effect"); //Visual Effect ADD_GROUP("Aura Effect", "aura_effect"); ClassDB::bind_method(D_METHOD("has_aura_effect_visual"), &SpellEffectVisualSimple::has_aura_effect_visual); ClassDB::bind_method(D_METHOD("get_aura_effect_visual_point"), &SpellEffectVisualSimple::get_aura_effect_visual_point); ClassDB::bind_method(D_METHOD("set_aura_effect_visual_point", "value"), &SpellEffectVisualSimple::set_aura_effect_visual_point); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_effect_visual_point", PROPERTY_HINT_ENUM, EntityEnums::BINDING_STRING_COMMON_CHARCATER_SKELETON_POINTS), "set_aura_effect_visual_point", "get_aura_effect_visual_point"); ClassDB::bind_method(D_METHOD("get_aura_effect_visual"), &SpellEffectVisualSimple::get_aura_effect_visual); ClassDB::bind_method(D_METHOD("set_aura_effect_visual", "value"), &SpellEffectVisualSimple::set_aura_effect_visual); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "aura_effect_visual", PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"), "set_aura_effect_visual", "get_aura_effect_visual"); } ================================================ FILE: data/spells/spell_effect_visual_simple.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef SPELL_EFFECT_VISUAL_SIMPLE_H #define SPELL_EFFECT_VISUAL_SIMPLE_H #include "spell_effect_visual.h" #include "scene/resources/packed_scene.h" #include "../../entity_enums.h" class SpellEffectVisualSimple : public SpellEffectVisual { GDCLASS(SpellEffectVisualSimple, SpellEffectVisual); public: bool has_spell_effect_visual(); EntityEnums::CommonCharacterSkeletonPoints get_spell_effect_visual_point(); void set_spell_effect_visual_point(EntityEnums::CommonCharacterSkeletonPoints point); Ref get_spell_effect_visual(); void set_spell_effect_visual(Ref value); bool has_spell_cast_finish_effect(); EntityEnums::CommonCharacterSkeletonPoints get_spell_cast_finish_effect_point(); void set_spell_cast_finish_effect_point(EntityEnums::CommonCharacterSkeletonPoints point); Ref get_spell_cast_finish_effect(); void set_spell_cast_finish_effect(Ref value); bool has_spell_cast_effect(); Ref get_spell_cast_effect(); void set_spell_cast_effect(Ref value); //VisualEffect bool has_aura_effect_visual(); EntityEnums::CommonCharacterSkeletonPoints get_aura_effect_visual_point(); void set_aura_effect_visual_point(EntityEnums::CommonCharacterSkeletonPoints point); Ref get_aura_effect_visual(); void set_aura_effect_visual(Ref value); SpellEffectVisualSimple(); ~SpellEffectVisualSimple(); protected: static void _bind_methods(); private: EntityEnums::CommonCharacterSkeletonPoints _effect_visual_point; Ref _effect_visual; EntityEnums::CommonCharacterSkeletonPoints _spell_cast_finish_effect_point; Ref _spell_cast_finish_effect; Ref _spell_cast_effect; EntityEnums::CommonCharacterSkeletonPoints _aura_effect_visual_point; Ref _aura_effect_visual; }; #endif ================================================ FILE: database/ess_resource_db.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "ess_resource_db.h" #include "../data/items/craft_recipe.h" #include "../data/species/entity_species_data.h" #include "../data/spells/spell.h" #include "../entities/data/entity_data.h" #include "../entities/resources/entity_resource.h" #include "../entities/skills/entity_skill_data.h" Ref ESSResourceDB::get_skill_for_armor_type(const int index) { ERR_FAIL_INDEX_V(index, ItemEnums::ARMOR_TYPE_MAX, Ref()); return _armor_type_skills[index]; } void ESSResourceDB::set_skill_for_armor_type(const int index, const Ref &aura) { ERR_FAIL_INDEX(index, ItemEnums::ARMOR_TYPE_MAX); _armor_type_skills[index] = aura; } void ESSResourceDB::add_entity_resource(Ref cls) { if (!cls.is_valid()) return; _entity_resources_id_to_path.insert(cls->get_id(), cls->get_path()); _entity_resources_path_to_id.insert(cls->get_path(), cls->get_id()); } Ref ESSResourceDB::get_entity_resource_path(const StringName &path) { return get_entity_resource(entity_resource_path_to_id(path)); } void ESSResourceDB::add_entity_skill(Ref cls) { if (!cls.is_valid()) return; _entity_skill_id_to_path.insert(cls->get_id(), cls->get_path()); _entity_skill_path_to_id.insert(cls->get_path(), cls->get_id()); } Ref ESSResourceDB::get_entity_skill_path(const StringName &path) { return get_entity_skill(entity_skill_path_to_id(path)); } void ESSResourceDB::add_entity_data(Ref cls) { if (!cls.is_valid()) return; _entity_data_id_to_path.insert(cls->get_id(), cls->get_path()); _entity_data_path_to_id.insert(cls->get_path(), cls->get_id()); } Ref ESSResourceDB::get_entity_data_path(const StringName &path) { return get_entity_data(entity_data_path_to_id(path)); } void ESSResourceDB::add_spell(Ref spell) { if (!spell.is_valid()) return; _spell_id_to_path.insert(spell->get_id(), spell->get_path()); _spell_path_to_id.insert(spell->get_path(), spell->get_id()); } Ref ESSResourceDB::get_spell_path(const StringName &path) { return get_spell(spell_path_to_id(path)); } void ESSResourceDB::add_craft_recipe(Ref cda) { if (!cda.is_valid()) return; _craft_recipe_id_to_path.insert(cda->get_id(), cda->get_path()); _craft_recipe_path_to_id.insert(cda->get_path(), cda->get_id()); } Ref ESSResourceDB::get_craft_recipe_path(const StringName &path) { return get_craft_recipe(craft_recipe_path_to_id(path)); } void ESSResourceDB::add_item_template(Ref cda) { if (!cda.is_valid()) return; _item_template_id_to_path.insert(cda->get_id(), cda->get_path()); _item_template_path_to_id.insert(cda->get_path(), cda->get_id()); } Ref ESSResourceDB::get_item_template_path(const StringName &path) { return get_item_template(item_template_path_to_id(path)); } void ESSResourceDB::add_entity_species_data(Ref cda) { if (!cda.is_valid()) return; _entity_species_id_to_path.insert(cda->get_id(), cda->get_path()); _entity_species_path_to_id.insert(cda->get_path(), cda->get_id()); } Ref ESSResourceDB::get_entity_species_data_path(const StringName &path) { return get_entity_species_data(entity_species_path_to_id(path)); } StringName ESSResourceDB::entity_resource_id_to_path(const int id) const { ERR_FAIL_COND_V(!_entity_resources_id_to_path.has(id), StringName()); return _entity_resources_id_to_path[id]; } int ESSResourceDB::entity_resource_path_to_id(const StringName &path) const { ERR_FAIL_COND_V(!_entity_resources_path_to_id.has(path), 0); return _entity_resources_path_to_id[path]; } StringName ESSResourceDB::entity_skill_id_to_path(const int id) const { ERR_FAIL_COND_V(!_entity_skill_id_to_path.has(id), StringName()); return _entity_skill_id_to_path[id]; } int ESSResourceDB::entity_skill_path_to_id(const StringName &path) const { ERR_FAIL_COND_V(!_entity_skill_path_to_id.has(path), 0); return _entity_skill_path_to_id[path]; } StringName ESSResourceDB::entity_data_id_to_path(const int id) const { ERR_FAIL_COND_V(!_entity_data_id_to_path.has(id), StringName()); return _entity_data_id_to_path[id]; } int ESSResourceDB::entity_data_path_to_id(const StringName &path) const { ERR_FAIL_COND_V(!_entity_data_path_to_id.has(path), 0); return _entity_data_path_to_id[path]; } StringName ESSResourceDB::spell_id_to_path(const int id) const { ERR_FAIL_COND_V(!_spell_id_to_path.has(id), StringName()); return _spell_id_to_path[id]; } int ESSResourceDB::spell_path_to_id(const StringName &path) const { ERR_FAIL_COND_V(!_spell_path_to_id.has(path), 0); return _spell_path_to_id[path]; } StringName ESSResourceDB::craft_recipe_id_to_path(const int id) const { ERR_FAIL_COND_V(!_craft_recipe_id_to_path.has(id), StringName()); return _craft_recipe_id_to_path[id]; } int ESSResourceDB::craft_recipe_path_to_id(const StringName &path) const { ERR_FAIL_COND_V(!_craft_recipe_path_to_id.has(path), 0); return _craft_recipe_path_to_id[path]; } StringName ESSResourceDB::item_template_id_to_path(const int id) const { ERR_FAIL_COND_V(!_item_template_id_to_path.has(id), StringName()); return _item_template_id_to_path[id]; } int ESSResourceDB::item_template_path_to_id(const StringName &path) const { ERR_FAIL_COND_V(!_item_template_path_to_id.has(path), 0); return _item_template_path_to_id[path]; } StringName ESSResourceDB::entity_species_id_to_path(const int id) const { ERR_FAIL_COND_V(!_entity_species_id_to_path.has(id), StringName()); return _entity_species_id_to_path[id]; } int ESSResourceDB::entity_species_path_to_id(const StringName &path) const { ERR_FAIL_COND_V(!_entity_species_path_to_id.has(path), 0); return _entity_species_path_to_id[path]; } void ESSResourceDB::clear() { } void ESSResourceDB::add_entity_resource_db(Ref other) { if (!other.is_valid()) return; for (int i = 0; i < other->get_entity_resource_count(); ++i) { add_entity_resource(other->get_entity_resource_index(i)); } for (int i = 0; i < other->get_entity_skill_count(); ++i) { add_entity_skill(other->get_entity_skill_index(i)); } for (int i = 0; i < other->get_entity_data_count(); ++i) { add_entity_data(other->get_entity_data_index(i)); } for (int i = 0; i < other->get_spell_count(); ++i) { add_spell(other->get_spell_index(i)); } for (int i = 0; i < other->get_craft_recipe_count(); ++i) { add_craft_recipe(other->get_craft_recipe_index(i)); } for (int i = 0; i < other->get_item_template_count(); ++i) { add_item_template(other->get_item_template_index(i)); } for (int i = 0; i < other->get_entity_species_data_count(); ++i) { add_entity_species_data(other->get_entity_species_data_index(i)); } } void ESSResourceDB::initialize() { if (has_method("_initialize")) call("_initialize"); } ESSResourceDB::ESSResourceDB() { } ESSResourceDB::~ESSResourceDB() { _entity_resources_path_to_id.clear(); _entity_resources_id_to_path.clear(); _entity_skill_path_to_id.clear(); _entity_skill_id_to_path.clear(); _entity_data_path_to_id.clear(); _entity_data_id_to_path.clear(); _spell_path_to_id.clear(); _spell_id_to_path.clear(); _craft_recipe_path_to_id.clear(); _craft_recipe_id_to_path.clear(); _item_template_path_to_id.clear(); _item_template_id_to_path.clear(); _entity_species_path_to_id.clear(); _entity_species_id_to_path.clear(); } void ESSResourceDB::_bind_methods() { ClassDB::bind_method(D_METHOD("get_skill_for_armor_type", "index"), &ESSResourceDB::get_skill_for_armor_type); ClassDB::bind_method(D_METHOD("set_skill_for_armor_type", "index", "aura"), &ESSResourceDB::set_skill_for_armor_type); for (int i = 0; i < ItemEnums::ARMOR_TYPE_MAX; ++i) { ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "skill_for_armor_type_" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "Spell"), "set_skill_for_armor_type", "get_skill_for_armor_type", i); } //EntityResource ClassDB::bind_method(D_METHOD("add_entity_resource", "cls"), &ESSResourceDB::add_entity_resource); ClassDB::bind_method(D_METHOD("get_entity_resource", "class_id"), &ESSResourceDB::get_entity_resource); ClassDB::bind_method(D_METHOD("get_entity_resource_index", "index"), &ESSResourceDB::get_entity_resource_index); ClassDB::bind_method(D_METHOD("get_entity_resource_count"), &ESSResourceDB::get_entity_resource_count); ClassDB::bind_method(D_METHOD("get_entity_resources"), &ESSResourceDB::get_entity_resources); ClassDB::bind_method(D_METHOD("set_entity_resources", "recipe"), &ESSResourceDB::set_entity_resources); ClassDB::bind_method(D_METHOD("get_entity_resource_path", "path"), &ESSResourceDB::get_entity_resource_path); ClassDB::bind_method(D_METHOD("entity_resource_id_to_path", "id"), &ESSResourceDB::entity_resource_id_to_path); ClassDB::bind_method(D_METHOD("entity_resource_path_to_id", "path"), &ESSResourceDB::entity_resource_path_to_id); //EntitySkills ClassDB::bind_method(D_METHOD("add_entity_skill", "cls"), &ESSResourceDB::add_entity_skill); ClassDB::bind_method(D_METHOD("get_entity_skill", "class_id"), &ESSResourceDB::get_entity_skill); ClassDB::bind_method(D_METHOD("get_entity_skill_index", "index"), &ESSResourceDB::get_entity_skill_index); ClassDB::bind_method(D_METHOD("get_entity_skill_count"), &ESSResourceDB::get_entity_skill_count); ClassDB::bind_method(D_METHOD("get_entity_skills"), &ESSResourceDB::get_entity_skills); ClassDB::bind_method(D_METHOD("set_entity_skills", "recipe"), &ESSResourceDB::set_entity_skills); ClassDB::bind_method(D_METHOD("get_entity_skill_path", "path"), &ESSResourceDB::get_entity_skill_path); ClassDB::bind_method(D_METHOD("entity_skill_id_to_path", "id"), &ESSResourceDB::entity_skill_id_to_path); ClassDB::bind_method(D_METHOD("entity_skill_path_to_id", "path"), &ESSResourceDB::entity_skill_path_to_id); //EntityData ClassDB::bind_method(D_METHOD("add_entity_data", "cls"), &ESSResourceDB::add_entity_data); ClassDB::bind_method(D_METHOD("get_entity_data", "class_id"), &ESSResourceDB::get_entity_data); ClassDB::bind_method(D_METHOD("get_entity_data_index", "index"), &ESSResourceDB::get_entity_data_index); ClassDB::bind_method(D_METHOD("get_entity_data_count"), &ESSResourceDB::get_entity_data_count); ClassDB::bind_method(D_METHOD("get_entity_datas"), &ESSResourceDB::get_entity_datas); ClassDB::bind_method(D_METHOD("set_entity_datas", "recipe"), &ESSResourceDB::set_entity_datas); ClassDB::bind_method(D_METHOD("get_entity_data_path", "path"), &ESSResourceDB::get_entity_data_path); ClassDB::bind_method(D_METHOD("entity_data_id_to_path", "id"), &ESSResourceDB::entity_data_id_to_path); ClassDB::bind_method(D_METHOD("entity_data_path_to_id", "path"), &ESSResourceDB::entity_data_path_to_id); //Spell ClassDB::bind_method(D_METHOD("add_spell", "spell"), &ESSResourceDB::add_spell); ClassDB::bind_method(D_METHOD("get_spell", "spell_id"), &ESSResourceDB::get_spell); ClassDB::bind_method(D_METHOD("get_spell_index", "index"), &ESSResourceDB::get_spell_index); ClassDB::bind_method(D_METHOD("get_spell_count"), &ESSResourceDB::get_spell_count); ClassDB::bind_method(D_METHOD("get_spells"), &ESSResourceDB::get_spells); ClassDB::bind_method(D_METHOD("set_spells", "recipe"), &ESSResourceDB::set_spells); ClassDB::bind_method(D_METHOD("get_spell_path", "path"), &ESSResourceDB::get_spell_path); ClassDB::bind_method(D_METHOD("spell_id_to_path", "id"), &ESSResourceDB::spell_id_to_path); ClassDB::bind_method(D_METHOD("spell_path_to_id", "path"), &ESSResourceDB::spell_path_to_id); //Craft Data ClassDB::bind_method(D_METHOD("add_craft_recipe", "craft_recipe"), &ESSResourceDB::add_craft_recipe); ClassDB::bind_method(D_METHOD("get_craft_recipe", "craft_recipe_id"), &ESSResourceDB::get_craft_recipe); ClassDB::bind_method(D_METHOD("get_craft_recipe_index", "index"), &ESSResourceDB::get_craft_recipe_index); ClassDB::bind_method(D_METHOD("get_craft_recipe_count"), &ESSResourceDB::get_craft_recipe_count); ClassDB::bind_method(D_METHOD("get_craft_recipes"), &ESSResourceDB::get_craft_recipes); ClassDB::bind_method(D_METHOD("set_craft_recipes", "recipe"), &ESSResourceDB::set_craft_recipes); ClassDB::bind_method(D_METHOD("get_craft_recipe_path", "path"), &ESSResourceDB::get_craft_recipe_path); ClassDB::bind_method(D_METHOD("craft_recipe_id_to_path", "id"), &ESSResourceDB::craft_recipe_id_to_path); ClassDB::bind_method(D_METHOD("craft_recipe_path_to_id", "path"), &ESSResourceDB::craft_recipe_path_to_id); //Item Templates ClassDB::bind_method(D_METHOD("add_item_template", "item_template"), &ESSResourceDB::add_item_template); ClassDB::bind_method(D_METHOD("get_item_template", "item_template_id"), &ESSResourceDB::get_item_template); ClassDB::bind_method(D_METHOD("get_item_template_index", "index"), &ESSResourceDB::get_item_template_index); ClassDB::bind_method(D_METHOD("get_item_template_count"), &ESSResourceDB::get_item_template_count); ClassDB::bind_method(D_METHOD("get_item_templates"), &ESSResourceDB::get_item_templates); ClassDB::bind_method(D_METHOD("set_item_templates", "recipe"), &ESSResourceDB::set_item_templates); ClassDB::bind_method(D_METHOD("get_item_template_path", "path"), &ESSResourceDB::get_item_template_path); ClassDB::bind_method(D_METHOD("item_template_id_to_path", "id"), &ESSResourceDB::item_template_id_to_path); ClassDB::bind_method(D_METHOD("item_template_path_to_id", "path"), &ESSResourceDB::item_template_path_to_id); //Entity Species ClassDB::bind_method(D_METHOD("add_entity_species_data", "pcd"), &ESSResourceDB::add_entity_species_data); ClassDB::bind_method(D_METHOD("get_entity_species_data", "pcd_id"), &ESSResourceDB::get_entity_species_data); ClassDB::bind_method(D_METHOD("get_entity_species_data_index", "index"), &ESSResourceDB::get_entity_species_data_index); ClassDB::bind_method(D_METHOD("get_entity_species_data_count"), &ESSResourceDB::get_entity_species_data_count); ClassDB::bind_method(D_METHOD("get_entity_species_datas"), &ESSResourceDB::get_entity_species_datas); ClassDB::bind_method(D_METHOD("set_entity_species_datas", "recipe"), &ESSResourceDB::set_entity_species_datas); ClassDB::bind_method(D_METHOD("get_entity_species_data_path", "path"), &ESSResourceDB::get_entity_species_data_path); ClassDB::bind_method(D_METHOD("entity_species_id_to_path", "id"), &ESSResourceDB::entity_species_id_to_path); ClassDB::bind_method(D_METHOD("entity_species_path_to_id", "path"), &ESSResourceDB::entity_species_path_to_id); ClassDB::bind_method(D_METHOD("clear"), &ESSResourceDB::clear); ClassDB::bind_method(D_METHOD("add_entity_resource_db", "other"), &ESSResourceDB::add_entity_resource_db); ////GDVIRTUAL_BIND("_initialize"); ClassDB::bind_method(D_METHOD("initialize"), &ESSResourceDB::initialize); } ================================================ FILE: database/ess_resource_db.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef ESS_RESOURCE_DB_H #define ESS_RESOURCE_DB_H #include "core/version.h" #include "core/io/resource.h" #include "core/templates/vector.h" #include "core/templates/hash_map.h" #include "core/string/ustring.h" #include "core/core_bind.h" #include "core/variant/variant.h" #include "../item_enums.h" class Spell; class EntityData; class CraftRecipe; class ItemTemplate; class EntityResource; class EntitySkillData; class EntityCreateInfo; class SpellCastInfo; class EntitySpeciesData; class ESSResourceDB : public Resource { GDCLASS(ESSResourceDB, Resource); public: Ref get_skill_for_armor_type(const int index); void set_skill_for_armor_type(const int index, const Ref &aura); virtual Ref get_entity_resource(int class_id) = 0; virtual Ref get_entity_resource_index(int index) = 0; virtual int get_entity_resource_count() = 0; virtual void add_entity_resource(Ref cls); virtual Vector get_entity_resources() const = 0; virtual void set_entity_resources(const Vector &data) = 0; Ref get_entity_resource_path(const StringName &path); StringName entity_resource_id_to_path(const int id) const; int entity_resource_path_to_id(const StringName &path) const; virtual Ref get_entity_skill(int class_id) = 0; virtual Ref get_entity_skill_index(int index) = 0; virtual int get_entity_skill_count() = 0; virtual void add_entity_skill(Ref cls); virtual Vector get_entity_skills() const = 0; virtual void set_entity_skills(const Vector &data) = 0; Ref get_entity_skill_path(const StringName &path); StringName entity_skill_id_to_path(const int id) const; int entity_skill_path_to_id(const StringName &path) const; virtual Ref get_entity_data(int class_id) = 0; virtual Ref get_entity_data_index(int index) = 0; virtual int get_entity_data_count() = 0; virtual void add_entity_data(Ref cls); virtual Vector get_entity_datas() const = 0; virtual void set_entity_datas(const Vector &data) = 0; Ref get_entity_data_path(const StringName &path); StringName entity_data_id_to_path(const int id) const; int entity_data_path_to_id(const StringName &path) const; virtual Ref get_spell(int spell_id) = 0; virtual Ref get_spell_index(int index) = 0; virtual int get_spell_count() = 0; virtual void add_spell(Ref spell); virtual Vector get_spells() const = 0; virtual void set_spells(const Vector &data) = 0; Ref get_spell_path(const StringName &path); StringName spell_id_to_path(const int id) const; int spell_path_to_id(const StringName &path) const; virtual Ref get_craft_recipe(int craft_id) = 0; virtual Ref get_craft_recipe_index(int index) = 0; virtual int get_craft_recipe_count() = 0; virtual void add_craft_recipe(Ref aura); virtual Vector get_craft_recipes() const = 0; virtual void set_craft_recipes(const Vector &data) = 0; Ref get_craft_recipe_path(const StringName &path); StringName craft_recipe_id_to_path(const int id) const; int craft_recipe_path_to_id(const StringName &path) const; virtual void add_item_template(Ref aura); virtual Ref get_item_template(int item_id) = 0; virtual Ref get_item_template_index(int index) = 0; virtual int get_item_template_count() = 0; virtual Vector get_item_templates() const = 0; virtual void set_item_templates(const Vector &data) = 0; Ref get_item_template_path(const StringName &path); StringName item_template_id_to_path(const int id) const; int item_template_path_to_id(const StringName &path) const; virtual void add_entity_species_data(Ref aura); virtual Ref get_entity_species_data(int item_id) = 0; virtual Ref get_entity_species_data_index(int index) = 0; virtual int get_entity_species_data_count() = 0; virtual Vector get_entity_species_datas() const = 0; virtual void set_entity_species_datas(const Vector &data) = 0; Ref get_entity_species_data_path(const StringName &path); StringName entity_species_id_to_path(const int id) const; int entity_species_path_to_id(const StringName &path) const; virtual void clear(); void add_entity_resource_db(Ref other); void initialize(); ESSResourceDB(); ~ESSResourceDB(); protected: static void _bind_methods(); Ref _armor_type_skills[ItemEnums::ARMOR_TYPE_MAX]; HashMap _entity_resources_id_to_path; HashMap _entity_resources_path_to_id; HashMap _entity_skill_id_to_path; HashMap _entity_skill_path_to_id; HashMap _entity_data_id_to_path; HashMap _entity_data_path_to_id; HashMap _spell_id_to_path; HashMap _spell_path_to_id; HashMap _craft_recipe_id_to_path; HashMap _craft_recipe_path_to_id; HashMap _item_template_id_to_path; HashMap _item_template_path_to_id; HashMap _entity_species_id_to_path; HashMap _entity_species_path_to_id; }; #endif ================================================ FILE: database/ess_resource_db_folders.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "ess_resource_db_folders.h" #include "../data/items/craft_recipe.h" #include "../data/species/entity_species_data.h" #include "../data/spells/spell.h" #include "../entities/data/entity_data.h" #include "../entities/resources/entity_resource.h" #include "../entities/skills/entity_skill_data.h" #include "core/io/dir_access.h" bool ESSResourceDBFolders::get_automatic_load() const { return _automatic_load; } void ESSResourceDBFolders::set_automatic_load(const bool load) { _automatic_load = load; } bool ESSResourceDBFolders::get_load_folders() const { return _load_folders; } void ESSResourceDBFolders::set_load_folders(const bool load) { _load_folders = load; } PoolStringArray ESSResourceDBFolders::get_folders() const { return _folders; } void ESSResourceDBFolders::set_folders(const PoolStringArray &data) { _folders = data; } void ESSResourceDBFolders::_initialize() { load_all(); } void ESSResourceDBFolders::load_all() { load_folders(); } void ESSResourceDBFolders::load_folders() { for (int i = 0; i < _folders.size(); ++i) { load_folder(_folders[i]); } } void ESSResourceDBFolders::load_folder(const String &folder) { Ref dir = DirAccess::open(folder); bool ew = folder.ends_with("/"); if (dir.is_valid()) { dir->list_dir_begin(); String filename; while (true) { filename = dir->get_next(); if (filename == "") break; if (!dir->current_is_dir()) { String path; if (ew) path = folder + filename; else path = folder + "/" + filename; Ref res = load_resource(path); ERR_CONTINUE(!res.is_valid()); add_resource(res); } } } else { print_error("An error occurred when trying to access the path."); } } void ESSResourceDBFolders::add_resource(const Ref &resource) { StringName cls = resource->get_class_name(); if (cls == "EntityResource") { add_entity_resource(resource); } else if (cls == "EntitySkillData") { add_entity_skill(resource); } else if (cls == "EntityData") { add_entity_data(resource); } else if (cls == "Spell") { add_spell(resource); } else if (cls == "CraftRecipe") { add_craft_recipe(resource); } else if (cls == "ItemTemplate") { add_item_template(resource); } else if (cls == "EntitySpeciesData") { add_entity_species_data(resource); } } Ref ESSResourceDBFolders::load_resource(const String &path, const String &type_hint) { return ResourceLoader::load(path, type_hint); } ESSResourceDBFolders::ESSResourceDBFolders() { _automatic_load = false; _xp_data_path = ""; if (_automatic_load) { call_deferred("load_all"); } } ESSResourceDBFolders::~ESSResourceDBFolders() { } void ESSResourceDBFolders::_bind_methods() { ClassDB::bind_method(D_METHOD("get_automatic_load"), &ESSResourceDBFolders::get_automatic_load); ClassDB::bind_method(D_METHOD("set_automatic_load", "load"), &ESSResourceDBFolders::set_automatic_load); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "automatic_load"), "set_automatic_load", "get_automatic_load"); ClassDB::bind_method(D_METHOD("get_folders"), &ESSResourceDBFolders::get_folders); ClassDB::bind_method(D_METHOD("set_folders", "recipe"), &ESSResourceDBFolders::set_folders); ADD_PROPERTY(PropertyInfo(Variant::POOL_STRING_ARRAY, "folders"), "set_folders", "get_folders"); //load ClassDB::bind_method(D_METHOD("_initialize"), &ESSResourceDBFolders::_initialize); ClassDB::bind_method(D_METHOD("load_all"), &ESSResourceDBFolders::load_all); ClassDB::bind_method(D_METHOD("load_folders"), &ESSResourceDBFolders::load_folders); ClassDB::bind_method(D_METHOD("load_folder", "folder"), &ESSResourceDBFolders::load_folder); ClassDB::bind_method(D_METHOD("add_resource", "resource"), &ESSResourceDBFolders::add_resource); ClassDB::bind_method(D_METHOD("load_resource", "path", "type_hint"), &ESSResourceDBFolders::load_resource, DEFVAL("")); } ================================================ FILE: database/ess_resource_db_folders.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef ESS_RESOURCE_DB_FOLDERS_H #define ESS_RESOURCE_DB_FOLDERS_H #include "core/version.h" #include "core/variant/variant.h" #include "core/templates/vector.h" #include "core/templates/hash_map.h" #include "core/string/ustring.h" #include "core/config/engine.h" #include "core/variant/array.h" #include "core/core_bind.h" #include "ess_resource_db_map.h" #include "scene/main/node.h" #include "../item_enums.h" #include "../defines.h" class Spell; class EntityData; class CraftRecipe; class ItemTemplate; class EntityResource; class EntitySkillData; class EntityCreateInfo; class SpellCastInfo; class EntitySpeciesData; class ESSResourceDBFolders : public ESSResourceDBMap { GDCLASS(ESSResourceDBFolders, ESSResourceDBMap); public: bool get_automatic_load() const; void set_automatic_load(const bool load); bool get_load_folders() const; void set_load_folders(const bool load); PoolStringArray get_folders() const; void set_folders(const PoolStringArray &folders); virtual void _initialize(); void load_all(); void load_folders(); void load_folder(const String &folder); void add_resource(const Ref &resource); Ref load_resource(const String &path, const String &type_hint = ""); ESSResourceDBFolders(); ~ESSResourceDBFolders(); protected: static void _bind_methods(); private: String _xp_data_path; PoolStringArray _folders; bool _automatic_load; bool _load_folders; }; #endif ================================================ FILE: database/ess_resource_db_map.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "ess_resource_db_map.h" #include "../data/items/craft_recipe.h" #include "../data/species/entity_species_data.h" #include "../data/spells/spell.h" #include "../entities/data/entity_data.h" #include "../entities/resources/entity_resource.h" #include "../entities/skills/entity_skill_data.h" Ref ESSResourceDBMap::get_entity_resource(int class_id) { //ERR_FAIL_COND_V_MSG(!_entity_resource_map.has(class_id), Ref(), "Could not find EntityResource! Id:" + String::num(class_id)); if (!_entity_resource_map.has(class_id)) { return Ref(); } return _entity_resource_map.get(class_id); } Ref ESSResourceDBMap::get_entity_resource_index(int index) { ERR_FAIL_INDEX_V(index, _entity_resources.size(), Ref(NULL)); return _entity_resources.get(index); } int ESSResourceDBMap::get_entity_resource_count() { return _entity_resources.size(); } void ESSResourceDBMap::add_entity_resource(Ref cls) { ERR_FAIL_COND(!cls.is_valid()); _entity_resources.push_back(cls); _entity_resource_map[cls->get_id()] = cls; ESSResourceDB::add_entity_resource(cls); } Vector ESSResourceDBMap::get_entity_resources() const { VARIANT_ARRAY_GET(_entity_resources); } void ESSResourceDBMap::set_entity_resources(const Vector &data) { _entity_resources.clear(); _entity_resource_map.clear(); for (int i = 0; i < data.size(); i++) { Ref d = Ref(data[i]); ERR_CONTINUE(!d.is_valid()); add_entity_resource(d); } } Ref ESSResourceDBMap::get_entity_skill(int class_id) { ERR_FAIL_COND_V_MSG(!_entity_skill_map.has(class_id), Ref(), "Could not find EntitySkillData! Id:" + String::num(class_id)); return _entity_skill_map.get(class_id); } Ref ESSResourceDBMap::get_entity_skill_index(int index) { ERR_FAIL_INDEX_V(index, _entity_skills.size(), Ref(NULL)); return _entity_skills.get(index); } int ESSResourceDBMap::get_entity_skill_count() { return _entity_skills.size(); } void ESSResourceDBMap::add_entity_skill(Ref cls) { ERR_FAIL_COND(!cls.is_valid()); _entity_skills.push_back(cls); _entity_skill_map[cls->get_id()] = cls; ESSResourceDB::add_entity_skill(cls); } Vector ESSResourceDBMap::get_entity_skills() const { VARIANT_ARRAY_GET(_entity_skills); } void ESSResourceDBMap::set_entity_skills(const Vector &data) { _entity_skills.clear(); _entity_skill_map.clear(); for (int i = 0; i < data.size(); i++) { Ref d = Ref(data[i]); ERR_CONTINUE(!d.is_valid()); add_entity_skill(d); } } Ref ESSResourceDBMap::get_entity_data(int class_id) { ERR_FAIL_COND_V_MSG(!_entity_data_map.has(class_id), Ref(), "Could not find EntityData! Id:" + String::num(class_id)); return _entity_data_map.get(class_id); } Ref ESSResourceDBMap::get_entity_data_index(int index) { ERR_FAIL_INDEX_V(index, _entity_datas.size(), Ref(NULL)); return _entity_datas.get(index); } int ESSResourceDBMap::get_entity_data_count() { return _entity_datas.size(); } void ESSResourceDBMap::add_entity_data(Ref cls) { ERR_FAIL_COND(!cls.is_valid()); _entity_datas.push_back(cls); _entity_data_map[cls->get_id()] = cls; ESSResourceDB::add_entity_data(cls); } Vector ESSResourceDBMap::get_entity_datas() const { VARIANT_ARRAY_GET(_entity_datas); } void ESSResourceDBMap::set_entity_datas(const Vector &data) { _craft_recipes.clear(); _craft_recipe_map.clear(); for (int i = 0; i < data.size(); i++) { Ref d = Ref(data[i]); ERR_CONTINUE(!d.is_valid()); add_entity_data(d); } } Ref ESSResourceDBMap::get_spell(int spell_id) { ERR_FAIL_COND_V_MSG(!_spell_map.has(spell_id), Ref(), "Could not find Spell! Id:" + String::num(spell_id)); return _spell_map.get(spell_id); } Ref ESSResourceDBMap::get_spell_index(int index) { ERR_FAIL_INDEX_V(index, _spells.size(), Ref(NULL)); return _spells.get(index); } int ESSResourceDBMap::get_spell_count() { return _spells.size(); } void ESSResourceDBMap::add_spell(Ref spell) { ERR_FAIL_COND(!spell.is_valid()); _spells.push_back(spell); _spell_map[spell->get_id()] = spell; ESSResourceDB::add_spell(spell); } Vector ESSResourceDBMap::get_spells() const { VARIANT_ARRAY_GET(_spells); } void ESSResourceDBMap::set_spells(const Vector &data) { _spells.clear(); _spell_map.clear(); for (int i = 0; i < data.size(); i++) { Ref d = Ref(data[i]); ERR_CONTINUE(!d.is_valid()); add_spell(d); } } //Craft Data void ESSResourceDBMap::add_craft_recipe(Ref cda) { ERR_FAIL_COND(!cda.is_valid()); _craft_recipes.push_back(cda); _craft_recipe_map[cda->get_id()] = cda; ESSResourceDB::add_craft_recipe(cda); } Ref ESSResourceDBMap::get_craft_recipe(int craft_id) { ERR_FAIL_COND_V_MSG(!_craft_recipe_map.has(craft_id), Ref(), "Could not find CraftRecipe! Id:" + String::num(craft_id)); return _craft_recipe_map.get(craft_id); } Ref ESSResourceDBMap::get_craft_recipe_index(int index) { ERR_FAIL_INDEX_V(index, _craft_recipes.size(), Ref()); return _craft_recipes.get(index); } int ESSResourceDBMap::get_craft_recipe_count() { return _craft_recipes.size(); } Vector ESSResourceDBMap::get_craft_recipes() const { VARIANT_ARRAY_GET(_craft_recipes); } void ESSResourceDBMap::set_craft_recipes(const Vector &data) { _craft_recipes.clear(); _craft_recipe_map.clear(); for (int i = 0; i < data.size(); i++) { Ref d = Ref(data[i]); ERR_CONTINUE(!d.is_valid()); add_craft_recipe(d); } } void ESSResourceDBMap::add_item_template(Ref cda) { ERR_FAIL_COND(!cda.is_valid()); _item_templates.push_back(cda); _item_template_map[cda->get_id()] = cda; ESSResourceDB::add_item_template(cda); } Ref ESSResourceDBMap::get_item_template(int item_id) { ERR_FAIL_COND_V_MSG(!_item_template_map.has(item_id), Ref(), "Could not find ItemTemplate! Id:" + String::num(item_id)); return _item_template_map.get(item_id); } Ref ESSResourceDBMap::get_item_template_index(int index) { ERR_FAIL_INDEX_V(index, _item_templates.size(), Ref()); return _item_templates.get(index); } int ESSResourceDBMap::get_item_template_count() { return _item_templates.size(); } Vector ESSResourceDBMap::get_item_templates() const { VARIANT_ARRAY_GET(_item_templates); } void ESSResourceDBMap::set_item_templates(const Vector &data) { _item_templates.clear(); _item_template_map.clear(); for (int i = 0; i < data.size(); i++) { Ref d = Ref(data[i]); ERR_CONTINUE(!d.is_valid()); add_item_template(d); } } void ESSResourceDBMap::add_entity_species_data(Ref cda) { ERR_FAIL_COND(!cda.is_valid()); _entity_species_datas.push_back(cda); _entity_species_data_map[cda->get_id()] = cda; ESSResourceDB::add_entity_species_data(cda); } Ref ESSResourceDBMap::get_entity_species_data(int item_id) { if (!_entity_species_data_map.has(item_id)) return Ref(); return _entity_species_data_map.get(item_id); } Ref ESSResourceDBMap::get_entity_species_data_index(int index) { ERR_FAIL_INDEX_V(index, _entity_species_datas.size(), Ref()); return _entity_species_datas.get(index); } int ESSResourceDBMap::get_entity_species_data_count() { return _entity_species_datas.size(); } Vector ESSResourceDBMap::get_entity_species_datas() const { VARIANT_ARRAY_GET(_entity_species_datas); } void ESSResourceDBMap::set_entity_species_datas(const Vector &data) { _entity_species_datas.clear(); _entity_species_data_map.clear(); for (int i = 0; i < data.size(); i++) { Ref d = Ref(data[i]); ERR_CONTINUE(!d.is_valid()); add_item_template(d); } } ESSResourceDBMap::ESSResourceDBMap() { } ESSResourceDBMap::~ESSResourceDBMap() { _entity_resources.clear(); _entity_resource_map.clear(); _entity_skills.clear(); _entity_skill_map.clear(); _entity_datas.clear(); _entity_data_map.clear(); _spells.clear(); _spell_map.clear(); _craft_recipes.clear(); _craft_recipe_map.clear(); _item_templates.clear(); _item_template_map.clear(); _entity_species_datas.clear(); _entity_species_data_map.clear(); } void ESSResourceDBMap::_bind_methods() { } ================================================ FILE: database/ess_resource_db_map.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef ESS_RESOURCE_DB_MAP_H #define ESS_RESOURCE_DB_MAP_H #include "ess_resource_db.h" #include "core/version.h" #include "core/variant/variant.h" #include "core/templates/vector.h" #include "core/templates/hash_map.h" #include "core/string/ustring.h" #include "core/config/engine.h" #include "core/variant/array.h" #include "core/core_bind.h" #include "scene/main/node.h" #include "../item_enums.h" #include "../defines.h" class Spell; class EntityData; class CraftRecipe; class ItemTemplate; class EntityResource; class EntitySkillData; class EntityCreateInfo; class SpellCastInfo; class EntitySpeciesData; class ESSResourceDBMap : public ESSResourceDB { GDCLASS(ESSResourceDBMap, ESSResourceDB); public: Ref get_entity_resource(int class_id); Ref get_entity_resource_index(int index); int get_entity_resource_count(); void add_entity_resource(Ref cls); Vector get_entity_resources() const; void set_entity_resources(const Vector &data); Ref get_entity_skill(int class_id); Ref get_entity_skill_index(int index); int get_entity_skill_count(); void add_entity_skill(Ref cls); Vector get_entity_skills() const; void set_entity_skills(const Vector &data); Ref get_entity_data(int class_id); Ref get_entity_data_index(int index); int get_entity_data_count(); void add_entity_data(Ref cls); Vector get_entity_datas() const; void set_entity_datas(const Vector &data); Ref get_spell(int spell_id); Ref get_spell_index(int index); int get_spell_count(); void add_spell(Ref spell); Vector get_spells() const; void set_spells(const Vector &data); Ref get_craft_recipe(int craft_id); Ref get_craft_recipe_index(int index); int get_craft_recipe_count(); void add_craft_recipe(Ref aura); Vector get_craft_recipes() const; void set_craft_recipes(const Vector &data); void add_item_template(Ref aura); Ref get_item_template(int item_id); Ref get_item_template_index(int index); int get_item_template_count(); Vector get_item_templates() const; void set_item_templates(const Vector &data); void add_entity_species_data(Ref aura); Ref get_entity_species_data(int item_id); Ref get_entity_species_data_index(int index); int get_entity_species_data_count(); Vector get_entity_species_datas() const; void set_entity_species_datas(const Vector &data); ESSResourceDBMap(); ~ESSResourceDBMap(); protected: static void _bind_methods(); private: Vector > _entity_resources; HashMap > _entity_resource_map; Vector > _entity_skills; HashMap > _entity_skill_map; Vector > _entity_datas; HashMap > _entity_data_map; Vector > _spells; HashMap > _spell_map; Vector > _craft_recipes; HashMap > _craft_recipe_map; Vector > _item_templates; HashMap > _item_template_map; Vector > _entity_species_datas; HashMap > _entity_species_data_map; }; #endif ================================================ FILE: database/ess_resource_db_static.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "ess_resource_db_static.h" #include "../data/items/craft_recipe.h" #include "../data/species/entity_species_data.h" #include "../data/spells/spell.h" #include "../entities/data/entity_data.h" #include "../entities/resources/entity_resource.h" #include "../entities/skills/entity_skill_data.h" bool ESSResourceDBStatic::get_remap_ids() const { return _remap_ids; } void ESSResourceDBStatic::set_remap_ids(const bool value) { _remap_ids = value; } Ref ESSResourceDBStatic::get_entity_resource(int id) { if (id < 0 || id >= _entity_resources.size()) return Ref(); return _entity_resources.get(id); } Ref ESSResourceDBStatic::get_entity_resource_index(int index) { ERR_FAIL_INDEX_V(index, _entity_resources.size(), Ref(NULL)); return _entity_resources.get(index); } int ESSResourceDBStatic::get_entity_resource_count() { return _entity_resources.size(); } void ESSResourceDBStatic::add_entity_resource(Ref cls) { if (_remap_ids && cls.is_valid()) cls->set_id(_entity_resources.size()); _entity_resources.push_back(cls); ESSResourceDB::add_entity_resource(cls); } Vector ESSResourceDBStatic::get_entity_resources() const { VARIANT_ARRAY_GET(_entity_resources); } void ESSResourceDBStatic::set_entity_resources(const Vector &data) { _entity_resources.clear(); for (int i = 0; i < data.size(); i++) { Ref d = Ref(data[i]); add_entity_resource(d); } } Ref ESSResourceDBStatic::get_entity_skill(int id) { if (id < 0 || id >= _entity_skills.size()) return Ref(); return _entity_skills.get(id); } Ref ESSResourceDBStatic::get_entity_skill_index(int index) { ERR_FAIL_INDEX_V(index, _entity_skills.size(), Ref(NULL)); return _entity_skills.get(index); } int ESSResourceDBStatic::get_entity_skill_count() { return _entity_skills.size(); } void ESSResourceDBStatic::add_entity_skill(Ref cls) { if (_remap_ids && cls.is_valid()) cls->set_id(_entity_skills.size()); _entity_skills.push_back(cls); ESSResourceDB::add_entity_skill(cls); } Vector ESSResourceDBStatic::get_entity_skills() const { VARIANT_ARRAY_GET(_entity_skills); } void ESSResourceDBStatic::set_entity_skills(const Vector &data) { _entity_skills.clear(); for (int i = 0; i < data.size(); i++) { Ref d = Ref(data[i]); add_entity_skill(d); } } Ref ESSResourceDBStatic::get_entity_data(int id) { if (id < 0 || id >= _entity_datas.size()) return Ref(); return _entity_datas.get(id); } Ref ESSResourceDBStatic::get_entity_data_index(int index) { ERR_FAIL_INDEX_V(index, _entity_datas.size(), Ref(NULL)); return _entity_datas.get(index); } int ESSResourceDBStatic::get_entity_data_count() { return _entity_datas.size(); } void ESSResourceDBStatic::add_entity_data(Ref cls) { if (_remap_ids && cls.is_valid()) cls->set_id(_entity_datas.size()); _entity_datas.push_back(cls); ESSResourceDB::add_entity_data(cls); } Vector ESSResourceDBStatic::get_entity_datas() const { VARIANT_ARRAY_GET(_entity_datas); } void ESSResourceDBStatic::set_entity_datas(const Vector &data) { _entity_datas.clear(); for (int i = 0; i < data.size(); i++) { Ref d = Ref(data[i]); add_entity_data(d); } } Ref ESSResourceDBStatic::get_spell(int id) { if (id < 0 || id >= _spells.size()) return Ref(); return _spells.get(id); } Ref ESSResourceDBStatic::get_spell_index(int index) { ERR_FAIL_INDEX_V(index, _spells.size(), Ref(NULL)); return _spells.get(index); } int ESSResourceDBStatic::get_spell_count() { return _spells.size(); } void ESSResourceDBStatic::add_spell(Ref spell) { if (_remap_ids && spell.is_valid()) spell->set_id(_spells.size()); _spells.push_back(spell); ESSResourceDB::add_spell(spell); } Vector ESSResourceDBStatic::get_spells() const { VARIANT_ARRAY_GET(_spells); } void ESSResourceDBStatic::set_spells(const Vector &data) { _spells.clear(); for (int i = 0; i < data.size(); i++) { Ref d = Ref(data[i]); add_spell(d); } } //Craft Data void ESSResourceDBStatic::add_craft_recipe(Ref cda) { if (_remap_ids && cda.is_valid()) cda->set_id(_craft_recipes.size()); _craft_recipes.push_back(cda); ESSResourceDB::add_craft_recipe(cda); } Ref ESSResourceDBStatic::get_craft_recipe(int id) { if (id < 0 || id >= _craft_recipes.size()) return Ref(); return _craft_recipes.get(id); } Ref ESSResourceDBStatic::get_craft_recipe_index(int index) { ERR_FAIL_INDEX_V(index, _craft_recipes.size(), Ref()); return _craft_recipes.get(index); } int ESSResourceDBStatic::get_craft_recipe_count() { return _craft_recipes.size(); } Vector ESSResourceDBStatic::get_craft_recipes() const { VARIANT_ARRAY_GET(_craft_recipes); } void ESSResourceDBStatic::set_craft_recipes(const Vector &data) { _craft_recipes.clear(); for (int i = 0; i < data.size(); i++) { Ref d = Ref(data[i]); add_craft_recipe(d); } } void ESSResourceDBStatic::add_item_template(Ref cda) { if (_remap_ids && cda.is_valid()) cda->set_id(_item_templates.size()); _item_templates.push_back(cda); ESSResourceDB::add_item_template(cda); } Ref ESSResourceDBStatic::get_item_template(int item_id) { if (item_id < 0 || item_id >= _item_templates.size()) return Ref(); return _item_templates.get(item_id); } Ref ESSResourceDBStatic::get_item_template_index(int index) { ERR_FAIL_INDEX_V(index, _item_templates.size(), Ref()); return _item_templates.get(index); } int ESSResourceDBStatic::get_item_template_count() { return _item_templates.size(); } Vector ESSResourceDBStatic::get_item_templates() const { VARIANT_ARRAY_GET(_item_templates); } void ESSResourceDBStatic::set_item_templates(const Vector &data) { _item_templates.clear(); for (int i = 0; i < data.size(); i++) { Ref d = Ref(data[i]); add_item_template(d); } } void ESSResourceDBStatic::add_entity_species_data(Ref cda) { if (_remap_ids && cda.is_valid()) cda->set_id(_entity_species_datas.size()); _entity_species_datas.push_back(cda); ESSResourceDB::add_entity_species_data(cda); } Ref ESSResourceDBStatic::get_entity_species_data(int id) { if (id < 0 || id > _entity_species_datas.size()) return Ref(); return _entity_species_datas.get(id); } Ref ESSResourceDBStatic::get_entity_species_data_index(int index) { ERR_FAIL_INDEX_V(index, _entity_species_datas.size(), Ref()); return _entity_species_datas.get(index); } int ESSResourceDBStatic::get_entity_species_data_count() { return _entity_species_datas.size(); } Vector ESSResourceDBStatic::get_entity_species_datas() const { VARIANT_ARRAY_GET(_entity_species_datas); } void ESSResourceDBStatic::set_entity_species_datas(const Vector &data) { _entity_species_datas.clear(); for (int i = 0; i < data.size(); i++) { Ref d = Ref(data[i]); add_entity_species_data(d); } } void ESSResourceDBStatic::clear() { _entity_resources.clear(); _entity_skills.clear(); _entity_datas.clear(); _spells.clear(); _craft_recipes.clear(); _item_templates.clear(); _entity_species_datas.clear(); } ESSResourceDBStatic::ESSResourceDBStatic() { _remap_ids = false; } ESSResourceDBStatic::~ESSResourceDBStatic() { _entity_resources.clear(); _entity_skills.clear(); _entity_datas.clear(); _spells.clear(); _craft_recipes.clear(); _item_templates.clear(); _entity_species_datas.clear(); } void ESSResourceDBStatic::_bind_methods() { ClassDB::bind_method(D_METHOD("get_remap_ids"), &ESSResourceDBStatic::get_remap_ids); ClassDB::bind_method(D_METHOD("set_remap_ids", "value"), &ESSResourceDBStatic::set_remap_ids); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "remap_ids"), "set_remap_ids", "get_remap_ids"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "entity_resources", PROPERTY_HINT_NONE, "17/17:EntityResource", PROPERTY_USAGE_DEFAULT, "EntityResource"), "set_entity_resources", "get_entity_resources"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "entity_skills", PROPERTY_HINT_NONE, "17/17:EntitySkillData", PROPERTY_USAGE_DEFAULT, "EntitySkillData"), "set_entity_skills", "get_entity_skills"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "entity_datas", PROPERTY_HINT_NONE, "17/17:EntityData", PROPERTY_USAGE_DEFAULT, "EntityData"), "set_entity_datas", "get_entity_datas"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "spells", PROPERTY_HINT_NONE, "17/17:Spell", PROPERTY_USAGE_DEFAULT, "Spell"), "set_spells", "get_spells"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "craft_recipes", PROPERTY_HINT_NONE, "17/17:CraftRecipe", PROPERTY_USAGE_DEFAULT, "CraftRecipe"), "set_craft_recipes", "get_craft_recipes"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "item_templates", PROPERTY_HINT_NONE, "17/17:ItemTemplate", PROPERTY_USAGE_DEFAULT, "ItemTemplate"), "set_item_templates", "get_item_templates"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "entity_species_datas", PROPERTY_HINT_NONE, "17/17:EntitySpeciesData", PROPERTY_USAGE_DEFAULT, "EntitySpeciesData"), "set_entity_species_datas", "get_entity_species_datas"); } ================================================ FILE: database/ess_resource_db_static.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef ESS_RESOURCE_DB_STATIC_H #define ESS_RESOURCE_DB_STATIC_H #include "core/version.h" #include "core/templates/hash_map.h" #include "ess_resource_db.h" #include "../item_enums.h" #include "../defines.h" class Spell; class EntityData; class CraftRecipe; class ItemTemplate; class EntityResource; class EntitySkillData; class EntityCreateInfo; class SpellCastInfo; class EntitySpeciesData; class ESSResourceDBStatic : public ESSResourceDB { GDCLASS(ESSResourceDBStatic, ESSResourceDB); public: bool get_remap_ids() const; void set_remap_ids(const bool value); String get_xp_data_path(); void set_xp_data_path(String path); PoolStringArray get_folders() const; void set_folders(const PoolStringArray &folders); Ref get_entity_resource(int class_id); Ref get_entity_resource_index(int index); int get_entity_resource_count(); void add_entity_resource(Ref cls); Vector get_entity_resources() const; void set_entity_resources(const Vector &data); Ref get_entity_skill(int class_id); Ref get_entity_skill_index(int index); int get_entity_skill_count(); void add_entity_skill(Ref cls); Vector get_entity_skills() const; void set_entity_skills(const Vector &data); Ref get_entity_data(int class_id); Ref get_entity_data_index(int index); int get_entity_data_count(); void add_entity_data(Ref cls); Vector get_entity_datas() const; void set_entity_datas(const Vector &data); Ref get_spell(int spell_id); Ref get_spell_index(int index); int get_spell_count(); void add_spell(Ref spell); Vector get_spells() const; void set_spells(const Vector &data); Ref get_craft_recipe(int craft_id); Ref get_craft_recipe_index(int index); int get_craft_recipe_count(); void add_craft_recipe(Ref aura); Vector get_craft_recipes() const; void set_craft_recipes(const Vector &data); void add_item_template(Ref aura); Ref get_item_template(int item_id); Ref get_item_template_index(int index); int get_item_template_count(); Vector get_item_templates() const; void set_item_templates(const Vector &data); void add_entity_species_data(Ref aura); Ref get_entity_species_data(int item_id); Ref get_entity_species_data_index(int index); int get_entity_species_data_count(); Vector get_entity_species_datas() const; void set_entity_species_datas(const Vector &data); void clear(); ESSResourceDBStatic(); ~ESSResourceDBStatic(); protected: static void _bind_methods(); private: bool _remap_ids; Vector > _entity_resources; Vector > _entity_skills; Vector > _entity_datas; Vector > _spells; Vector > _craft_recipes; Vector > _item_templates; Vector > _entity_species_datas; }; #endif ================================================ FILE: defines.h ================================================ #ifndef ESS_DEFINES_H #define ESS_DEFINES_H #include "core/version.h" #if VERSION_MAJOR >= 4 #define GODOT4 true #endif //includes #if GODOT4 #define spatial_h_path "scene/3d/node_3d.h" #define visual_server_h_path include "servers/rendering_server.h" //#include "core/input/input_event.h" //#include "editor/plugins/node_3d_editor_plugin.h" //#include "scene/3d/camera_3d.h" #else #define spatial_h_path "scene/3d/spatial.h" #define visual_server_h_path include "servers/visual_server.h" //#include "core/os/input.h" //#include "editor/plugins/spatial_editor_plugin.h" //#include "scene/3d/camera.h" #endif //Type Defines #if GODOT4 #define PhysicsDirectSpaceState PhysicsDirectSpaceState3D #define SpatialEditor Node3DEditor #define SpatialEditorPlugin Node3DEditorPlugin #define SpatialEditorViewport Node3DEditorViewport #define PoolStringArray PackedStringArray #define REAL FLOAT #define POOL_STRING_ARRAY PACKED_STRING_ARRAY #define POOL_INT_ARRAY PACKED_INT32_ARRAY #define POOL_REAL_ARRAY PACKED_FLOAT32_ARRAY #define Spatial Node3D typedef class RenderingServer VisualServer; typedef class RenderingServer VS; #define PoolVector3Array PackedVector3Array #define PoolVector2Array PackedVector2Array #define PoolColorArray PackedColorArray #define PoolIntArray PackedInt64Array #define PoolRealArray PackedFloat32Array //toodo figure out a way to have this //#define Variant::CallError Callable::CallError #endif #if GODOT4 #define VARIANT_ARRAY_GET(arr) \ Vector r; \ for (int i = 0; i < arr.size(); i++) { \ r.push_back(arr[i]); \ } \ return r; #else #define VARIANT_ARRAY_GET(arr) \ Vector r; \ for (int i = 0; i < arr.size(); i++) { \ r.push_back(arr[i].get_ref_ptr()); \ } \ return r; #endif #define VARIANT_ARRAY_SET(arr, arr_into, type) \ arr_into.clear(); \ for (int i = 0; i < arr.size(); i++) { \ Ref e = Ref(arr[i]); \ arr_into.push_back(e); \ } #if GODOT4 //TODO do this properly #define INSTANCE_VALIDATE(var) var #define CONNECT(sig, obj, target_method_class, method) connect(sig, callable_mp(obj, &target_method_class::method)) #define DISCONNECT(sig, obj, target_method_class, method) disconnect(sig, callable_mp(obj, &target_method_class::method)) #else #define INSTANCE_VALIDATE(var) ObjectDB::instance_validate(var) #define CONNECT(sig, obj, target_method_class, method) connect(sig, obj, #method) #define DISCONNECT(sig, obj, target_method_class, method) disconnect(sig, obj, #method) #endif #endif ================================================ FILE: doc_classes/AIFormation.xml ================================================ Class for scriptable AI formations. Not yet used. Needs pet support. ================================================ FILE: doc_classes/ActionBarButtonEntry.xml ================================================ Stores the data for an actionbar button. ProfileManager uses it. ================================================ FILE: doc_classes/ActionBarEntry.xml ================================================ Stores the data for an actionbar. Also see [ProfileManager]. ================================================ FILE: doc_classes/ActionBarProfile.xml ================================================ Stores all actionbar-related data for a class. Also see [ProfileManager]. ================================================ FILE: doc_classes/AuraApplyInfo.xml ================================================ Helper class, which is used to apply an [Aura] to an [Entity]. ================================================ FILE: doc_classes/AuraData.xml ================================================ Stores an [Aura]'s runtime data on an [Entity]. ================================================ FILE: doc_classes/AuraGroup.xml ================================================ Used to make some [Aura]s override each other. Only one [Aura] with the same group is allowed on an [Entity] by the same caster by default. For example if an [Entity] wants to apply the same [Aura] except different ranks to a target, this is how you can prevent it easily. ================================================ FILE: doc_classes/Bag.xml ================================================ Stores [Entity] inventory. ================================================ FILE: doc_classes/CharacterAtlas.xml ================================================ ================================================ FILE: doc_classes/CharacterAtlasEntry.xml ================================================ ================================================ FILE: doc_classes/CharacterBones.xml ================================================ ================================================ FILE: doc_classes/CharacterSkeleton2D.xml ================================================ ================================================ FILE: doc_classes/CharacterSkeleton3D.xml ================================================ 3d implementation for [CharacterSkeleton]. Note: Most of the logic implementation for this is still in gdscript. It will be ported. ================================================ FILE: doc_classes/CharacterSpec.xml ================================================ Contains data for a character's specialization. Specialization in ESS means talents, and talent tabs. ================================================ FILE: doc_classes/ClassProfile.xml ================================================ Contains all profile information for an [Entity]'s class. Related to [ProfileManager]. ================================================ FILE: doc_classes/ComplexLevelStatData.xml ================================================ Per level stat information for an [Entity]. ================================================ FILE: doc_classes/CraftRecipe.xml ================================================ Recipe data for the crafting system. ================================================ FILE: doc_classes/CraftRecipeHelper.xml ================================================ Contains one item entry for [CraftRecipes]s ================================================ FILE: doc_classes/ESDragAndDrop.xml ================================================ Drag and drop helper class for the actionbars, and inventory. ================================================ FILE: doc_classes/ESS.xml ================================================ The ESS singleton. Gives easy access to entity and spell related data, providing easy lookups. Make sure that you add everything both server and clientside before use, because the system uses ids (get_id()) for server clinet communications. This also means that ids should be unique per resources for every ESS-related resources. For example you shouldn't register 2 spells with id 1 (you will get an error), but you can register a [Spell] with id1 and an [Aura] with an id 1. Also grants access easy to ESS-related project settings. ================================================ FILE: doc_classes/ESSEntitySpawner.xml ================================================ ================================================ FILE: doc_classes/ESSMaterialCache.xml ================================================ ================================================ FILE: doc_classes/ESSMaterialCachePCM.xml ================================================ ================================================ FILE: doc_classes/ESSResourceDB.xml ================================================ ================================================ FILE: doc_classes/ESSResourceDBFolders.xml ================================================ ================================================ FILE: doc_classes/ESSResourceDBMap.xml ================================================ ================================================ FILE: doc_classes/ESSResourceDBStatic.xml ================================================ ================================================ FILE: doc_classes/Entity.xml ================================================ Represents an [Entity] inside the world. Entities can be players, mobs, chests, or any kind of interactable things. Functions starting, or having an 's' in them (like cooldown_adds, or equip_applys_item etc) are only called, or meant to be called by serverside code. Functions with a 'c' in them (like cooldown_addc, equip_deapplyc_item etc) are only called, or meant to be called from clientside code. Functions that have a virtual variant starting with an underscore, should be called, they will call the virtual version. They will check if the virtual properly exists, also usually they check if the parameters are valid, so you don't have to do it every time in gdscript. ================================================ FILE: doc_classes/EntityAI.xml ================================================ You can implement AI for [Entities] with this. ================================================ FILE: doc_classes/EntityClassData.xml ================================================ Contains all of information for an [Entity]'s class. (Ingame class) ================================================ FILE: doc_classes/EntityCreateInfo.xml ================================================ Helper class used for [Entity] creation, and setup. ================================================ FILE: doc_classes/EntityData.xml ================================================ Contains all data for a given [Entity]. Think of this as all the data for a mob, or a player. ================================================ FILE: doc_classes/EntityDataContainer.xml ================================================ ================================================ FILE: doc_classes/EntityEnums.xml ================================================ Contains lots of general-use enums for entities. ================================================ FILE: doc_classes/EntityResource.xml ================================================ An instance of an entity resource. Resource in this context is things like mana. ================================================ FILE: doc_classes/EntityResourceCostData.xml ================================================ Contains a resource cost. Resource in this context is things like mana. ================================================ FILE: doc_classes/EntityResourceCostDataHealth.xml ================================================ ================================================ FILE: doc_classes/EntityResourceCostDataResource.xml ================================================ ================================================ FILE: doc_classes/EntityResourceHealth.xml ================================================ ================================================ FILE: doc_classes/EntityResourceSpeed.xml ================================================ ================================================ FILE: doc_classes/EntitySkill.xml ================================================ Contains runtime skill data for an [Entity]. Skills can be things like axes. You can change values for these using scripts. ================================================ FILE: doc_classes/EntitySkillData.xml ================================================ Contains skill data for an [Entity]. Skills can be things like axes. ================================================ FILE: doc_classes/EntitySpeciesData.xml ================================================ Contains visual data for a species. ================================================ FILE: doc_classes/EquipmentData.xml ================================================ Stores equipment information. ================================================ FILE: doc_classes/InputProfile.xml ================================================ Will store keybind information. [ProfileManager] related. ================================================ FILE: doc_classes/InputProfileModifier.xml ================================================ Stores data for bindable modifiers. Not yet implemented. ================================================ FILE: doc_classes/InputProfileModifierEntry.xml ================================================ One key entry for a key. ================================================ FILE: doc_classes/ItemContainerData.xml ================================================ ================================================ FILE: doc_classes/ItemContainerDataEntry.xml ================================================ ================================================ FILE: doc_classes/ItemEnums.xml ================================================ Contains lots of general-use enums for items. ================================================ FILE: doc_classes/ItemInstance.xml ================================================ Runtime information for an item. ================================================ FILE: doc_classes/ItemTemplate.xml ================================================ Contains item information. ================================================ FILE: doc_classes/LevelStatData.xml ================================================ Base class for storing level stat information for entities. ================================================ FILE: doc_classes/LootDataBase.xml ================================================ Base class for storing loot information for entities. ================================================ FILE: doc_classes/ModelVisual.xml ================================================ Contains an item's visual information. ================================================ FILE: doc_classes/ModelVisualEntry.xml ================================================ One Entry for [ModelVisual]. ================================================ FILE: doc_classes/PlayerProfile.xml ================================================ Stores the data for a player. Also see [ProfileManager]. ================================================ FILE: doc_classes/ProfileManager.xml ================================================ Stores, saves, loads per class profile data. Should be added as an autoload, or at least is should be in the scene before spawning entities. ================================================ FILE: doc_classes/PropDataEntity.xml ================================================ ================================================ FILE: doc_classes/SimpleLevelStatData.xml ================================================ Simple per-level [Stat] information for entities. ================================================ FILE: doc_classes/SkeletonModelEntry.xml ================================================ Runtime model item entry helper for skeletons. Used by [CharacterSkeleton3D] for example. ================================================ FILE: doc_classes/SpeciesInstance.xml ================================================ ================================================ FILE: doc_classes/SpeciesModelData.xml ================================================ Stores model information for [EntitySpeciesData]. ================================================ FILE: doc_classes/Spell.xml ================================================ Base [Spell] class. Contains data, and callbacks for spell scripts. Inherit from this to create spells with different functionality. ================================================ FILE: doc_classes/SpellCastInfo.xml ================================================ Contains spell cast related information, for easy manipulation with auras, spell callbacks, etc. ================================================ FILE: doc_classes/SpellCooldownManipulationData.xml ================================================ Contains data for easy spell cooldown manipulations. Not yet implemented. ================================================ FILE: doc_classes/SpellDamageInfo.xml ================================================ Contains damage information. It is passed around in callbacks, so things can modify values. (absorbs, immunities etc.) ================================================ FILE: doc_classes/SpellEffectVisual.xml ================================================ Base class for storing spell visual information, like particle effects. ================================================ FILE: doc_classes/SpellEffectVisualSimple.xml ================================================ Simple implementation od [SpellEfectVisual]. ================================================ FILE: doc_classes/SpellEnums.xml ================================================ Contains lots of general-use enums for spells. ================================================ FILE: doc_classes/SpellFollowProjectile3D.xml ================================================ ================================================ FILE: doc_classes/SpellHealInfo.xml ================================================ Contains heal information. It is passed around in callbacks, so things can modify values. (absorbs, immunities etc.) ================================================ FILE: doc_classes/StatData.xml ================================================ Contains a [Stat]'s data. ================================================ FILE: doc_classes/VendorItemData.xml ================================================ Contains vendor item data for an [Entity]/[EntityData]. ================================================ FILE: doc_classes/VendorItemDataEntry.xml ================================================ Contains one entry for a [VendorItemData]. ================================================ FILE: drag_and_drop/es_drag_and_drop.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "es_drag_and_drop.h" const String ESDragAndDrop::BINDING_STRING_ES_DRAG_AND_DROP_TYPE = "None,Spell,Item,Inventory Item,Equipped Item"; Node *ESDragAndDrop::get_origin() const { return _origin; } void ESDragAndDrop::set_origin(Node *origin) { _origin = origin; } ESDragAndDrop::ESDragAndDropType ESDragAndDrop::get_type() const { return _type; } void ESDragAndDrop::set_type(const ESDragAndDrop::ESDragAndDropType type) { _type = type; } StringName ESDragAndDrop::get_item_path() const { return _item_path; } void ESDragAndDrop::set_item_path(const StringName &item_path) { _item_path = item_path; } ESDragAndDrop::ESDragAndDrop() { _type = ES_DRAG_AND_DROP_TYPE_NONE; _origin = NULL; } void ESDragAndDrop::_bind_methods() { ClassDB::bind_method(D_METHOD("get_origin"), &ESDragAndDrop::get_origin); ClassDB::bind_method(D_METHOD("set_origin", "id"), &ESDragAndDrop::set_origin); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "origin", PROPERTY_HINT_RESOURCE_TYPE, "Node"), "set_origin", "get_origin"); ClassDB::bind_method(D_METHOD("get_type"), &ESDragAndDrop::get_type); ClassDB::bind_method(D_METHOD("set_type", "type"), &ESDragAndDrop::set_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, BINDING_STRING_ES_DRAG_AND_DROP_TYPE), "set_type", "get_type"); ClassDB::bind_method(D_METHOD("get_item_path"), &ESDragAndDrop::get_item_path); ClassDB::bind_method(D_METHOD("set_item_path", "id"), &ESDragAndDrop::set_item_path); ADD_PROPERTY(PropertyInfo(Variant::STRING, "item_path"), "set_item_path", "get_item_path"); BIND_ENUM_CONSTANT(ES_DRAG_AND_DROP_TYPE_NONE); BIND_ENUM_CONSTANT(ES_DRAG_AND_DROP_TYPE_SPELL); BIND_ENUM_CONSTANT(ES_DRAG_AND_DROP_TYPE_ITEM); BIND_ENUM_CONSTANT(ES_DRAG_AND_DROP_TYPE_INVENTORY_ITEM); BIND_ENUM_CONSTANT(ES_DRAG_AND_DROP_TYPE_EQUIPPED_ITEM); } ================================================ FILE: drag_and_drop/es_drag_and_drop.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef ES_DRAG_AND_DROP_H #define ES_DRAG_AND_DROP_H #include "core/version.h" #include "core/object/ref_counted.h" #include "core/string/ustring.h" #include "scene/main/node.h" class ESDragAndDrop : public RefCounted { GDCLASS(ESDragAndDrop, RefCounted); public: static const String BINDING_STRING_ES_DRAG_AND_DROP_TYPE; enum ESDragAndDropType { ES_DRAG_AND_DROP_TYPE_NONE = 0, ES_DRAG_AND_DROP_TYPE_SPELL = 1, ES_DRAG_AND_DROP_TYPE_ITEM = 2, ES_DRAG_AND_DROP_TYPE_INVENTORY_ITEM = 3, ES_DRAG_AND_DROP_TYPE_EQUIPPED_ITEM = 4, }; Node *get_origin() const; void set_origin(Node *owner); ESDragAndDropType get_type() const; void set_type(const ESDragAndDropType type); StringName get_item_path() const; void set_item_path(const StringName &item_path); ESDragAndDrop(); protected: static void _bind_methods(); private: Node *_origin; ESDragAndDropType _type; StringName _item_path; }; VARIANT_ENUM_CAST(ESDragAndDrop::ESDragAndDropType); #endif ================================================ FILE: editor/ess_editor_plugin.cpp ================================================ /* Copyright (c) 2020-2022 Péter Magyar 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 "ess_editor_plugin.h" #include "core/version.h" void ESSEditorPlugin::fix_ids(Variant param) { } ESSEditorPlugin::ESSEditorPlugin(EditorNode *p_node) { editor = p_node; //editor->add_tool_menu_item("ESS: make ids unique", this, "fix_ids"); } ESSEditorPlugin::~ESSEditorPlugin() { } void ESSEditorPlugin::_bind_methods() { ClassDB::bind_method(D_METHOD("fix_ids"), &ESSEditorPlugin::fix_ids); } ================================================ FILE: editor/ess_editor_plugin.h ================================================ /* Copyright (c) 2020-2022 Péter Magyar 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. */ #ifndef ESS_EDITOR_PLUGIN_H #define ESS_EDITOR_PLUGIN_H #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "core/version.h" class ESSEditorPlugin : public EditorPlugin { GDCLASS(ESSEditorPlugin, EditorPlugin); EditorNode *editor; protected: static void _bind_methods(); public: virtual String get_name() const { return "ESSEditorPlugin"; } bool has_main_screen() const { return false; } virtual void edit(Object *p_object) {} virtual bool handles(Object *p_object) const { return false; } virtual void make_visible(bool p_visible) {} void fix_ids(Variant param); ESSEditorPlugin(EditorNode *p_node); ~ESSEditorPlugin(); }; #endif ================================================ FILE: entities/ai/entity_ai.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "entity_ai.h" #include "../entity.h" #include "../../infos/spell_cast_info.h" #include "../../data/items/item_instance.h" #include "../../entities/auras/aura_data.h" #include "../../entities/resources/entity_resource.h" #include "../../pipelines/spell_damage_info.h" #include "../../pipelines/spell_heal_info.h" #include "../../defines.h" bool EntityAI::get_enabled() { return _enabled; } void EntityAI::set_enabled(bool value) { _enabled = value; } void EntityAI::set_owner(Entity *entity) { if (entity == _owner) return; _owner = entity; call("_on_set_owner"); } void EntityAI::set_owner_bind(Node *entity) { if (!entity) { return; } Entity *e = cast_to(entity); if (!e) { return; } return set_owner(e); } Entity *EntityAI::get_owner() { return _owner; } Vector EntityAI::get_spec_distribution() { return _spec_distribution; } void EntityAI::set_spec_distribution(Vector data) { _spec_distribution = data; } int EntityAI::get_spec_variance() { return _spec_variance; } void EntityAI::set_spec_variance(int value) { _spec_variance = value; } EntityEnums::AIStates EntityAI::get_state() { return _state; } void EntityAI::set_state(EntityEnums::AIStates state) { _state = state; } EntityEnums::AIStates EntityAI::get_force_state() { return _force_state; } void EntityAI::set_force_state(EntityEnums::AIStates state) { _force_state = state; } void EntityAI::set_editor_description(const String &p_editor_description) { set_meta("_editor_description_", p_editor_description); } String EntityAI::get_editor_description() const { if (has_meta("_editor_description_")) { return get_meta("_editor_description_"); } else { return ""; } } void EntityAI::update(float delta) { ERR_FAIL_COND(!INSTANCE_VALIDATE(_owner)); if (has_method("_update")) call("_update", delta); } void EntityAI::pet_update(float delta) { ERR_FAIL_COND(!INSTANCE_VALIDATE(_owner)); if (has_method("_pet_update")) call("_pet_update", delta); } void EntityAI::move(float delta) { ERR_FAIL_COND(!INSTANCE_VALIDATE(_owner)); if (has_method("_move")) call("_move", delta); } void EntityAI::pet_move(float delta) { ERR_FAIL_COND(!INSTANCE_VALIDATE(_owner)); if (has_method("_pet_move")) call("_pet_move", delta); } void EntityAI::_on_set_owner() { } void EntityAI::start_casting(int spell_id, Entity *caster, float spellScale) { //if (_entity_class_data.is_valid()) // _entity_class_data->start_casting(spell_id, caster, spellScale); } void EntityAI::notification_saura(int what, Ref data) { ERR_FAIL_COND(!data.is_valid()); if (has_method("_notification_saura")) call("_notification_saura", what, data); } void EntityAI::notification_sheal(int what, Ref info) { ERR_FAIL_COND(!info.is_valid()); if (has_method("_notification_sheal")) call("_notification_sheal", what, info); } void EntityAI::notification_scast(int what, Ref info) { ERR_FAIL_COND(!info.is_valid()); if (has_method("_notification_scast")) call("_notification_scast", what, info); } void EntityAI::notification_sdamage(int what, Ref info) { ERR_FAIL_COND(!info.is_valid()); if (has_method("_notification_sdamage")) call("_notification_sdamage", what, info); } void EntityAI::notification_sdeath(Entity *entity) { if (has_method("_notification_sdeath")) call("_notification_sdeath", entity); } void EntityAI::notification_sdeath_bind(Node *entity) { ERR_FAIL_COND(entity == NULL); Entity *e = Object::cast_to(entity); ERR_FAIL_COND(e == NULL); notification_sdeath(e); } void EntityAI::notification_scooldown_added(int id, float value) { if (has_method("_notification_scooldown_added")) call("_notification_scooldown_added", id, value); } void EntityAI::notification_scooldown_removed(int id, float value) { if (has_method("_notification_scooldown_removed")) call("_notification_scooldown_removed", id, value); } void EntityAI::notification_scategory_cooldown_added(int id, float value) { if (has_method("_notification_scategory_cooldown_added")) call("_notification_scategory_cooldown_added", id, value); } void EntityAI::notification_scategory_cooldown_removed(int id, float value) { if (has_method("_notification_scategory_cooldown_removed")) call("_notification_scategory_cooldown_removed", id, value); } void EntityAI::notification_sgcd_started(Entity *entity, float gcd) { if (has_method("_notification_sgcd_started")) call("_notification_sgcd_started", entity, gcd); } void EntityAI::notification_sgcd_finished(Entity *entity) { if (has_method("_notification_sgcd_finished")) call("_notification_sgcd_finished", entity); } void EntityAI::notification_sgcd_started_bind(Node *entity, float gcd) { ERR_FAIL_COND(entity == NULL); Entity *e = Object::cast_to(entity); ERR_FAIL_COND(e == NULL); notification_sgcd_started(e, gcd); } void EntityAI::notification_sgcd_finished_bind(Node *entity) { ERR_FAIL_COND(entity == NULL); Entity *e = Object::cast_to(entity); ERR_FAIL_COND(e == NULL); notification_sgcd_finished(e); } void EntityAI::notification_sxp_gained(Entity *entity, int value) { if (has_method("_notification_sxp_gained")) call("_notification_sxp_gained", entity, value); } void EntityAI::notification_sxp_gained_bind(Node *entity, int value) { ERR_FAIL_COND(!INSTANCE_VALIDATE(entity)); Entity *e = Object::cast_to(entity); ERR_FAIL_COND(e == NULL); notification_sxp_gained(e, value); } void EntityAI::notification_slevel_up(Entity *entity, int value) { if (has_method("_notification_slevel_up")) call("_notification_slevel_up", entity); } void EntityAI::notification_slevel_up_bind(Node *entity, int value) { ERR_FAIL_COND(!INSTANCE_VALIDATE(entity)); Entity *e = Object::cast_to(entity); ERR_FAIL_COND(e == NULL); notification_slevel_up(e, value); } void EntityAI::notification_sentity_resource_added(Ref resource) { if (has_method("_notification_sentity_resource_added")) call("_notification_sentity_resource_added", resource); } void EntityAI::notification_sentity_resource_removed(Ref resource) { if (has_method("_notification_sentity_resource_removed")) call("_notification_sentity_resource_removed", resource); } //Equipment bool EntityAI::equip_should_deny(Entity *entity, int equip_slot, Ref item) { if (has_method("_equip_should_deny")) if (call("_equip_should_deny", entity, equip_slot, item)) return true; return false; } bool EntityAI::equip_should_deny_bind(Node *entity, int equip_slot, Ref item) { ERR_FAIL_COND_V(!INSTANCE_VALIDATE(entity), false); Entity *e = Object::cast_to(entity); ERR_FAIL_COND_V(e == NULL, false); return equip_should_deny(e, equip_slot, item); } void EntityAI::equip_son_success(Entity *entity, int equip_slot, Ref item, Ref old_item, int bag_slot) { if (has_method("_equip_son_success")) call("_equip_son_success", entity, equip_slot, item, old_item, bag_slot); } void EntityAI::equip_son_success_bind(Node *entity, int equip_slot, Ref item, Ref old_item, int bag_slot) { ERR_FAIL_COND(!INSTANCE_VALIDATE(entity)); Entity *e = Object::cast_to(entity); ERR_FAIL_COND(e == NULL); equip_son_success(e, equip_slot, item, old_item, bag_slot); } void EntityAI::equip_son_fail(Entity *entity, int equip_slot, Ref item, Ref old_item, int bag_slot) { if (has_method("_equip_son_fail")) call("_equip_son_fail", entity, equip_slot, item, old_item, bag_slot); } void EntityAI::equip_son_fail_bind(Node *entity, int equip_slot, Ref item, Ref old_item, int bag_slot) { ERR_FAIL_COND(!INSTANCE_VALIDATE(entity)); Entity *e = Object::cast_to(entity); ERR_FAIL_COND(e == NULL); equip_son_fail(e, equip_slot, item, old_item, bag_slot); } void EntityAI::equip_con_success(Entity *entity, int equip_slot, Ref item, Ref old_item, int bag_slot) { if (has_method("_equip_con_success")) call("_equip_con_success", entity, equip_slot, item, old_item, bag_slot); } void EntityAI::equip_con_success_bind(Node *entity, int equip_slot, Ref item, Ref old_item, int bag_slot) { ERR_FAIL_COND(!INSTANCE_VALIDATE(entity)); Entity *e = Object::cast_to(entity); ERR_FAIL_COND(e == NULL); equip_con_success(e, equip_slot, item, old_item, bag_slot); } void EntityAI::equip_con_fail(Entity *entity, int equip_slot, Ref item, Ref old_item, int bag_slot) { if (has_method("_equip_con_fail")) call("_equip_con_fail", entity, equip_slot, item, old_item, bag_slot); } void EntityAI::equip_con_fail_bind(Node *entity, int equip_slot, Ref item, Ref old_item, int bag_slot) { ERR_FAIL_COND(!INSTANCE_VALIDATE(entity)); Entity *e = Object::cast_to(entity); ERR_FAIL_COND(e == NULL); equip_con_fail(e, equip_slot, item, old_item, bag_slot); } EntityAI::EntityAI() { _enabled = true; _owner = NULL; _spec_variance = 0; _state = EntityEnums::AI_STATE_OFF; _force_state = EntityEnums::AI_STATE_OFF; } EntityAI::~EntityAI() { _spec_distribution.clear(); } void EntityAI::_bind_methods() { //GDVIRTUAL_BIND("_on_set_owner"); //GDVIRTUAL_BIND("_update", "delta"); //GDVIRTUAL_BIND("_pet_update", "delta"); //GDVIRTUAL_BIND("_move", "delta"); //GDVIRTUAL_BIND("_pet_move", "delta"); ClassDB::bind_method(D_METHOD("get_enabled"), &EntityAI::get_enabled); ClassDB::bind_method(D_METHOD("set_enabled", "value"), &EntityAI::set_enabled); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "get_enabled"), "set_enabled", "get_enabled"); ClassDB::bind_method(D_METHOD("get_owner"), &EntityAI::get_owner); ClassDB::bind_method(D_METHOD("set_owner", "entity"), &EntityAI::set_owner_bind); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Entity", 0), "set_owner", "get_owner"); ClassDB::bind_method(D_METHOD("get_spec_distribution"), &EntityAI::get_spec_distribution); ClassDB::bind_method(D_METHOD("set_spec_distribution", "value"), &EntityAI::set_spec_distribution); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "spec_distribution"), "set_spec_distribution", "get_spec_distribution"); ClassDB::bind_method(D_METHOD("get_spec_variance"), &EntityAI::get_spec_variance); ClassDB::bind_method(D_METHOD("set_spec_variance", "value"), &EntityAI::set_spec_variance); ADD_PROPERTY(PropertyInfo(Variant::INT, "spec_variance"), "set_spec_variance", "get_spec_variance"); ClassDB::bind_method(D_METHOD("get_state"), &EntityAI::get_state); ClassDB::bind_method(D_METHOD("set_state", "state"), &EntityAI::set_state); ADD_PROPERTY(PropertyInfo(Variant::INT, "state", PROPERTY_HINT_ENUM, EntityEnums::BINDING_STRING_AI_STATES), "set_state", "get_state"); ClassDB::bind_method(D_METHOD("get_force_state"), &EntityAI::get_force_state); ClassDB::bind_method(D_METHOD("set_force_state", "state"), &EntityAI::set_force_state); ADD_PROPERTY(PropertyInfo(Variant::INT, "force_state", PROPERTY_HINT_ENUM, EntityEnums::BINDING_STRING_AI_STATES), "set_force_state", "get_force_state"); ClassDB::bind_method(D_METHOD("set_editor_description", "editor_description"), &EntityAI::set_editor_description); ClassDB::bind_method(D_METHOD("get_editor_description"), &EntityAI::get_editor_description); ADD_PROPERTY(PropertyInfo(Variant::STRING, "editor_description", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "set_editor_description", "get_editor_description"); ClassDB::bind_method(D_METHOD("update", "delta"), &EntityAI::update); ClassDB::bind_method(D_METHOD("pet_update", "delta"), &EntityAI::pet_update); ClassDB::bind_method(D_METHOD("move", "delta"), &EntityAI::move); ClassDB::bind_method(D_METHOD("pet_move", "delta"), &EntityAI::pet_move); ClassDB::bind_method(D_METHOD("_on_set_owner"), &EntityAI::_on_set_owner); //EventHandlers //GDVIRTUAL_BIND("_notification_saura", "what", "data", "AuraData"); //GDVIRTUAL_BIND("_notification_sheal", "what", "info", "SpellHealInfo"); //GDVIRTUAL_BIND("_notification_scast", "what", "info", "SpellCastInfo"); //GDVIRTUAL_BIND("_notification_sdamage", "what", "info", "SpellDamageInfo"); ClassDB::bind_method(D_METHOD("notification_saura", "what", "data"), &EntityAI::notification_saura); ClassDB::bind_method(D_METHOD("notification_sheal", "what", "info"), &EntityAI::notification_sheal); ClassDB::bind_method(D_METHOD("notification_scast", "what", "info"), &EntityAI::notification_scast); ClassDB::bind_method(D_METHOD("notification_sdamage", "what", "info"), &EntityAI::notification_sdamage); ClassDB::bind_method(D_METHOD("notification_sdeath", "data"), &EntityAI::notification_sdeath_bind); ClassDB::bind_method(D_METHOD("notification_scooldown_added", "cooldown"), &EntityAI::notification_scooldown_added); ClassDB::bind_method(D_METHOD("notification_scooldown_removed", "cooldown"), &EntityAI::notification_scooldown_removed); ClassDB::bind_method(D_METHOD("notification_scategory_cooldown_added", "category_cooldown"), &EntityAI::notification_scategory_cooldown_added); ClassDB::bind_method(D_METHOD("notification_scategory_cooldown_removed", "category_cooldown"), &EntityAI::notification_scategory_cooldown_removed); ClassDB::bind_method(D_METHOD("notification_sgcd_started", "entity", "gcd"), &EntityAI::notification_sgcd_started_bind); ClassDB::bind_method(D_METHOD("notification_sgcd_finished", "entity"), &EntityAI::notification_sgcd_finished_bind); ClassDB::bind_method(D_METHOD("notification_sxp_gained", "entity", "value"), &EntityAI::notification_sxp_gained_bind); ClassDB::bind_method(D_METHOD("notification_slevel_up", "entity", "value"), &EntityAI::notification_slevel_up_bind); ClassDB::bind_method(D_METHOD("notification_sentity_resource_added", "resource"), &EntityAI::notification_sentity_resource_added); ClassDB::bind_method(D_METHOD("notification_sentity_resource_removed", "resource"), &EntityAI::notification_sentity_resource_removed); //GDVIRTUAL_BIND("_notification_sdeath", "data", "Entity"); //GDVIRTUAL_BIND("_notification_scooldown_added", "id", "value"); //GDVIRTUAL_BIND("_notification_scooldown_removed", "id", "value"); //GDVIRTUAL_BIND("_notification_scategory_cooldown_added", "id", "value"); //GDVIRTUAL_BIND("_notification_scategory_cooldown_removed", "id", "value"); //GDVIRTUAL_BIND("_notification_sgcd_started", "entity", "Entity", "gcd"); //GDVIRTUAL_BIND("_notification_sgcd_finished", "entity", "Entity"); //GDVIRTUAL_BIND("_notification_sxp_gained", "entity", "Entity", "value"); //GDVIRTUAL_BIND("_notification_slevel_up", "entity", "Entity", "value"); //GDVIRTUAL_BIND("_notification_sentity_resource_added", "resource", "EntityResource"); //GDVIRTUAL_BIND("_notification_sentity_resource_removed", "resource", "EntityResource"); //Equipment //GDVIRTUAL_BIND("_equip_should_deny", "entity", PROPERTY_HINT_RESOURCE_TYPE, "Entity", "equip_slot", "item", "ItemInstance"); //GDVIRTUAL_BIND("_equip_son_success", PropertyInfo(Variant::OBJECT, "entity", PROPERTY_HINT_RESOURCE_TYPE, "Entity"), PropertyInfo(Variant::INT, "equip_slot", "item", PROPERTY_HINT_RESOURCE_TYPE, "ItemInstance", "old_item", "ItemInstance", "bag_slot"); //GDVIRTUAL_BIND("_equip_son_fail", PropertyInfo(Variant::OBJECT, "entity", PROPERTY_HINT_RESOURCE_TYPE, "Entity"), PropertyInfo(Variant::INT, "equip_slot", "item", PROPERTY_HINT_RESOURCE_TYPE, "ItemInstance", "old_item", "ItemInstance", "bag_slot"); //GDVIRTUAL_BIND("_equip_con_success", PropertyInfo(Variant::OBJECT, "entity", PROPERTY_HINT_RESOURCE_TYPE, "Entity"), PropertyInfo(Variant::INT, "equip_slot", "item", PROPERTY_HINT_RESOURCE_TYPE, "ItemInstance", "old_item", "ItemInstance", "bag_slot"); //GDVIRTUAL_BIND("_equip_con_fail", PropertyInfo(Variant::OBJECT, "entity", PROPERTY_HINT_RESOURCE_TYPE, "Entity"), PropertyInfo(Variant::INT, "equip_slot", "item", PROPERTY_HINT_RESOURCE_TYPE, "ItemInstance", "old_item", "ItemInstance", "bag_slot"); ClassDB::bind_method(D_METHOD("equip_should_deny", "entity", "equip_slot", "item"), &EntityAI::equip_should_deny_bind); ClassDB::bind_method(D_METHOD("equip_son_success", "entity", "equip_slot", "item", "old_item", "bag_slot"), &EntityAI::equip_son_success_bind); ClassDB::bind_method(D_METHOD("equip_son_fail", "entity", "equip_slot", "item", "old_item", "bag_slot"), &EntityAI::equip_son_fail_bind); ClassDB::bind_method(D_METHOD("equip_con_success", "entity", "equip_slot", "item", "old_item", "bag_slot"), &EntityAI::equip_con_success_bind); ClassDB::bind_method(D_METHOD("equip_con_fail", "entity", "equip_slot", "item", "old_item", "bag_slot"), &EntityAI::equip_con_fail_bind); } ================================================ FILE: entities/ai/entity_ai.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef ENTITY_AI_H #define ENTITY_AI_H #include "core/version.h" #include "core/io/resource.h" #include "scene/main/node.h" #include "../../entity_enums.h" class AuraData; class SpellHealInfo; class SpellDamageInfo; class SpellCastInfo; class ItemInstance; class EntityResource; class Entity; class EntityAI : public Resource { GDCLASS(EntityAI, Resource); public: bool get_enabled(); void set_enabled(bool value); void set_owner(Entity *entity); void set_owner_bind(Node *entity); Entity *get_owner(); Vector get_spec_distribution(); void set_spec_distribution(Vector data); int get_spec_variance(); void set_spec_variance(int value); EntityEnums::AIStates get_state(); void set_state(EntityEnums::AIStates state); EntityEnums::AIStates get_force_state(); void set_force_state(EntityEnums::AIStates state); void set_editor_description(const String &p_editor_description); String get_editor_description() const; void update(float delta); void pet_update(float delta); void move(float delta); void pet_move(float delta); void _on_set_owner(); //// Spell System //// void start_casting(int spell_id, Entity *caster, float spellScale); void notification_saura(int what, Ref data); void notification_sheal(int what, Ref info); void notification_scast(int what, Ref info); void notification_sdamage(int what, Ref info); void notification_sdeath(Entity *entity); void notification_sdeath_bind(Node *entity); void notification_scooldown_added(int id, float value); void notification_scooldown_removed(int id, float value); void notification_scategory_cooldown_added(int id, float value); void notification_scategory_cooldown_removed(int id, float value); void notification_sgcd_started(Entity *entity, float gcd); void notification_sgcd_finished(Entity *entity); void notification_sgcd_started_bind(Node *entity, float gcd); void notification_sgcd_finished_bind(Node *entity); void notification_sxp_gained(Entity *entity, int value); void notification_sxp_gained_bind(Node *entity, int value); void notification_slevel_up(Entity *entity, int value); void notification_slevel_up_bind(Node *entity, int value); void notification_sentity_resource_added(Ref resource); void notification_sentity_resource_removed(Ref resource); //Equipment bool equip_should_deny(Entity *entity, int equip_slot, Ref item); bool equip_should_deny_bind(Node *entity, int equip_slot, Ref item); void equip_son_success(Entity *entity, int equip_slot, Ref item, Ref old_item, int bag_slot); void equip_son_success_bind(Node *entity, int equip_slot, Ref item, Ref old_item, int bag_slot); void equip_son_fail(Entity *entity, int equip_slot, Ref item, Ref old_item, int bag_slot); void equip_son_fail_bind(Node *entity, int equip_slot, Ref item, Ref old_item, int bag_slot); void equip_con_success(Entity *entity, int equip_slot, Ref item, Ref old_item, int bag_slot); void equip_con_success_bind(Node *entity, int equip_slot, Ref item, Ref old_item, int bag_slot); void equip_con_fail(Entity *entity, int equip_slot, Ref item, Ref old_item, int bag_slot); void equip_con_fail_bind(Node *entity, int equip_slot, Ref item, Ref old_item, int bag_slot); EntityAI(); ~EntityAI(); protected: static void _bind_methods(); private: bool _enabled; Entity *_owner; Vector _spec_distribution; int _spec_variance; EntityEnums::AIStates _state; EntityEnums::AIStates _force_state; }; #endif ================================================ FILE: entities/auras/aura_data.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "aura_data.h" #include "core/version.h" #include "../../data/spells/spell.h" #include "../../database/ess_resource_db.h" #include "../../singletons/ess.h" #include "../entity.h" #include "../../defines.h" float AuraData::damage_get_count() { return _damage_already_taken; } void AuraData::damage_set_count(int damageTaken) { _damage_already_taken = damageTaken; } int AuraData::get_aura_id() { return _aura_id; } void AuraData::set_aura_id(int value) { _aura_id = value; } bool AuraData::get_is_timed() { return _is_timed; } void AuraData::set_is_timed(bool value) { _is_timed = value; } float AuraData::get_remaining_time() { return _remaining_time; } void AuraData::set_remaining_time(float value) { _remaining_time = value; } bool AuraData::update(float delta) { if (_tick > 0.01) { _time_since_last_tick += delta; while (_time_since_last_tick >= _tick) { _time_since_last_tick -= _tick; ++_unhandled_ticks; } } if (_is_timed) { _remaining_time -= delta; if (_remaining_time <= 0) { _remaining_time = 0; return true; } } return false; } Entity *AuraData::get_owner() { return _owner; } void AuraData::set_owner(Entity *value) { _owner = value; } void AuraData::set_owner_bind(Node *value) { if (!value) { return; } Entity *e = cast_to(value); if (!e) { return; } _owner = e; } Entity *AuraData::caster_get() { return _caster; } void AuraData::caster_set(Entity *value) { _caster = value; if (_caster == _owner) { _caster_path = NodePath("."); return; } if (!value) { _caster_path = NodePath(); return; } if (_caster->is_inside_tree()) { _caster_path = _caster->get_path(); } } void AuraData::caster_set_bind(Node *value) { if (!value) { caster_set(NULL); return; } Entity *e = cast_to(value); if (!e) { return; } caster_set(e); } NodePath AuraData::caster_get_path() { return _caster_path; } void AuraData::caster_set_path(NodePath value) { _caster_path = value; } float AuraData::spell_scale_get() { return _spell_scale; } void AuraData::spell_scale_set(float value) { _spell_scale = value; } Ref AuraData::get_aura() { //if (_aura == NULL) { //TODO fix! //_aura = Auras::getInstance()->GetData(get_aura_id()); //} return _aura; } void AuraData::set_aura(Ref aura) { _aura = aura; if (aura.is_valid()) _aura_path = aura->get_path(); else _aura_path = ""; } int AuraData::damage_get() { return _damage; } void AuraData::damage_set(int value) { _damage = value; } float AuraData::get_tick() { return _tick; } void AuraData::set_tick(float value) { _tick = value; } float AuraData::get_time_since_last_tick() { return _time_since_last_tick; } void AuraData::set_time_since_last_tick(float value) { _time_since_last_tick = value; } int AuraData::get_unhandled_ticks() { return _unhandled_ticks; } void AuraData::set_unhandled_ticks(int value) { _unhandled_ticks = value; } int AuraData::damage_get_taken() { return _damage_already_taken; } void AuraData::damage_set_taken(int value) { _damage_already_taken = value; } void AuraData::refresh(float remaining_time) { _remaining_time = remaining_time; _damage_already_taken = 0; _time_since_last_tick = (float)0; //_diminishing_level_count += 1; } /* void AuraData::refresh(float remaining_time) { _diminishing_level_count += 1; } void AuraData::refresh(float remaining_time) { _damage_already_taken = 0; } void AuraData::refresh(float remaining_time) { _remaining_time = _remaining_time; _time_since_last_tick = (float)0; } void AuraData::refresh(float remaining_time) { _time_since_last_tick = (float)0; }*/ int AuraData::heal_get() { return _heal; } void AuraData::heal_set(int value) { _heal = value; } int AuraData::get_remaining_absorb() { return _remaining_absorb; } void AuraData::set_remaining_absorb(int value) { _remaining_absorb = value; } float AuraData::get_slow() { return _slow; } void AuraData::set_slow(float value) { _slow = value; } void AuraData::resolve_references(Node *owner) { ERR_FAIL_COND(!INSTANCE_VALIDATE(owner)); ERR_FAIL_COND(!owner->is_inside_tree()); _owner = Object::cast_to(owner); if (owner->is_inside_tree()) { _caster = Object::cast_to(owner->get_node_or_null(_caster_path)); } } Dictionary AuraData::to_dict() { return call("_to_dict"); } void AuraData::from_dict(const Dictionary &dict) { call("_from_dict", dict); } Dictionary AuraData::_to_dict() { Dictionary dict; dict["aura_id"] = _aura_id; dict["aura_path"] = _aura_path; dict["remaining_time"] = _remaining_time; dict["caster_path"] = _caster_path; dict["spell_scale"] = _spell_scale; dict["aura_group"] = _aura_group; dict["aura_id"] = _aura->get_id(); dict["is_timed"] = _is_timed; dict["damage"] = _damage; dict["heal"] = _heal; dict["slow"] = _slow; dict["remaining_absorb"] = _remaining_absorb; dict["tick"] = _tick; dict["time_since_last_tick"] = _time_since_last_tick; dict["damage_already_taken"] = _damage_already_taken; dict["unhandled_ticks"] = _unhandled_ticks; return dict; } void AuraData::_from_dict(const Dictionary &dict) { ERR_FAIL_COND(dict.is_empty()); ERR_FAIL_COND(!ESS::get_singleton()->get_resource_db().is_valid()); _aura_id = dict.get("aura_id", 0); _aura_path = dict.get("aura_path", ""); _remaining_time = dict.get("remaining_time", 0); _caster_path = dict.get("caster_path", NodePath()); _spell_scale = dict.get("spell_scale", 0); _aura_group = dict.get("aura_group", 0); //int aura_id = dict.get("aura_id", 0); _aura = ESS::get_singleton()->get_resource_db()->get_spell_path(_aura_path); _is_timed = dict.get("is_timed", true); _damage = dict.get("damage", 0); _heal = dict.get("heal", 0); _slow = dict.get("slow", 0); _remaining_absorb = dict.get("remaining_absorb", 0); _tick = dict.get("tick", 0); _time_since_last_tick = dict.get("time_since_last_tick", 0); _damage_already_taken = dict.get("damage_already_taken", 0); _unhandled_ticks = dict.get("unhandled_ticks", 0); } Array AuraData::to_send_array() { return call("_to_send_array"); } void AuraData::from_send_array(const Array &arr) { call("_from_send_array", arr); } Array AuraData::_to_send_array() { Array arr; arr.append(_aura_id); arr.append(_remaining_time); return arr; } void AuraData::_from_send_array(const Array &arr) { ERR_FAIL_COND(arr.size() < 2); _aura_id = arr.get(0); _remaining_time = arr.get(1); } AuraData::AuraData() { _owner = NULL; _aura_id = 0; _remaining_time = 0; _caster = NULL; _spell_scale = 0; _aura_group = 0; _is_timed = false; _damage = 0; _heal = 0; _slow = 0; _remaining_absorb = 0; _tick = 0; _time_since_last_tick = 0; _damage_already_taken = 0; _unhandled_ticks = 0; } void AuraData::_bind_methods() { ClassDB::bind_method(D_METHOD("get_aura_id"), &AuraData::get_aura_id); ClassDB::bind_method(D_METHOD("set_aura_id", "value"), &AuraData::set_aura_id); ADD_PROPERTY(PropertyInfo(Variant::INT, "aura_id"), "set_aura_id", "get_aura_id"); ClassDB::bind_method(D_METHOD("get_is_timed"), &AuraData::get_is_timed); ClassDB::bind_method(D_METHOD("set_is_timed", "value"), &AuraData::set_is_timed); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_timed"), "set_is_timed", "get_is_timed"); ClassDB::bind_method(D_METHOD("get_remaining_time"), &AuraData::get_remaining_time); ClassDB::bind_method(D_METHOD("set_remaining_time", "value"), &AuraData::set_remaining_time); ADD_PROPERTY(PropertyInfo(Variant::REAL, "remaining_time"), "set_remaining_time", "get_remaining_time"); ClassDB::bind_method(D_METHOD("get_owner"), &AuraData::get_owner); ClassDB::bind_method(D_METHOD("set_owner", "value"), &AuraData::set_owner_bind); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Entity", 0), "set_owner", "get_owner"); ClassDB::bind_method(D_METHOD("caster_get"), &AuraData::caster_get); ClassDB::bind_method(D_METHOD("caster_set", "value"), &AuraData::caster_set_bind); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "caster", PROPERTY_HINT_RESOURCE_TYPE, "Entity", 0), "caster_set", "caster_get"); ClassDB::bind_method(D_METHOD("caster_get_path"), &AuraData::caster_get_path); ClassDB::bind_method(D_METHOD("caster_set_path", "value"), &AuraData::caster_set_path); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "caster_path"), "caster_set_path", "caster_get_path"); ClassDB::bind_method(D_METHOD("get_aura"), &AuraData::get_aura); ClassDB::bind_method(D_METHOD("set_aura", "value"), &AuraData::set_aura); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "aura", PROPERTY_HINT_RESOURCE_TYPE, "Aura"), "set_aura", "get_aura"); ClassDB::bind_method(D_METHOD("refresh", "remaining"), &AuraData::refresh); ClassDB::bind_method(D_METHOD("damage_get"), &AuraData::damage_get); ClassDB::bind_method(D_METHOD("damage_set", "value"), &AuraData::damage_set); ADD_PROPERTY(PropertyInfo(Variant::INT, "damage"), "damage_set", "damage_get"); ClassDB::bind_method(D_METHOD("damage_get_count"), &AuraData::damage_get_count); ClassDB::bind_method(D_METHOD("damage_set_count", "value"), &AuraData::damage_set_count); ADD_PROPERTY(PropertyInfo(Variant::INT, "damage_count"), "damage_set_count", "damage_get_count"); ClassDB::bind_method(D_METHOD("get_tick"), &AuraData::get_tick); ClassDB::bind_method(D_METHOD("set_tick", "value"), &AuraData::set_tick); ADD_PROPERTY(PropertyInfo(Variant::REAL, "tick"), "set_tick", "get_tick"); ClassDB::bind_method(D_METHOD("get_time_since_last_tick"), &AuraData::get_time_since_last_tick); ClassDB::bind_method(D_METHOD("set_time_since_last_tick", "value"), &AuraData::set_time_since_last_tick); ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_since_last_tick"), "set_time_since_last_tick", "get_time_since_last_tick"); ClassDB::bind_method(D_METHOD("get_unhandled_ticks"), &AuraData::get_unhandled_ticks); ClassDB::bind_method(D_METHOD("set_unhandled_ticks", "value"), &AuraData::set_unhandled_ticks); ADD_PROPERTY(PropertyInfo(Variant::INT, "unhandled_ticks"), "set_unhandled_ticks", "get_unhandled_ticks"); ClassDB::bind_method(D_METHOD("damage_get_taken"), &AuraData::damage_get_taken); ClassDB::bind_method(D_METHOD("damage_set_taken", "value"), &AuraData::damage_set_taken); ADD_PROPERTY(PropertyInfo(Variant::INT, "damage_taken"), "damage_set_taken", "damage_get_taken"); ClassDB::bind_method(D_METHOD("heal_get"), &AuraData::heal_get); ClassDB::bind_method(D_METHOD("heal_set", "value"), &AuraData::heal_set); ADD_PROPERTY(PropertyInfo(Variant::INT, "heal"), "heal_set", "heal_get"); ClassDB::bind_method(D_METHOD("get_remaining_absorb"), &AuraData::get_remaining_absorb); ClassDB::bind_method(D_METHOD("set_remaining_absorb", "value"), &AuraData::set_remaining_absorb); ADD_PROPERTY(PropertyInfo(Variant::INT, "remaining_absorb"), "heal_set", "get_remaining_absorb"); ClassDB::bind_method(D_METHOD("get_slow"), &AuraData::get_slow); ClassDB::bind_method(D_METHOD("set_slow", "value"), &AuraData::set_slow); ADD_PROPERTY(PropertyInfo(Variant::REAL, "slow"), "set_slow", "get_slow"); //Serialization //GDVIRTUAL_BIND("_from_dict", "dict"); //GDVIRTUAL_BIND("_to_dict"); ClassDB::bind_method(D_METHOD("from_dict", "dict"), &AuraData::from_dict); ClassDB::bind_method(D_METHOD("to_dict"), &AuraData::to_dict); ClassDB::bind_method(D_METHOD("_from_dict", "dict"), &AuraData::_from_dict); ClassDB::bind_method(D_METHOD("_to_dict"), &AuraData::_to_dict); //Networking //GDVIRTUAL_BIND("_to_send_array"); //GDVIRTUAL_BIND("_from_send_array", "arr"); ClassDB::bind_method(D_METHOD("to_send_array"), &AuraData::to_send_array); ClassDB::bind_method(D_METHOD("from_send_array", "arr"), &AuraData::from_send_array); ClassDB::bind_method(D_METHOD("_to_send_array"), &AuraData::_to_send_array); ClassDB::bind_method(D_METHOD("_from_send_array", "arr"), &AuraData::_from_send_array); } ================================================ FILE: entities/auras/aura_data.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef AURA_DATA_H #define AURA_DATA_H #include "core/version.h" #include "core/io/resource.h" #include "core/variant/array.h" #include "core/variant/dictionary.h" #include "../../spell_enums.h" class Spell; class Entity; class AuraData : public Resource { GDCLASS(AuraData, Resource); public: int get_aura_id(); void set_aura_id(int value); bool get_is_timed(); void set_is_timed(bool value); float get_remaining_time(); void set_remaining_time(float value); bool update(float delta); Entity *get_owner(); void set_owner(Entity *value); void set_owner_bind(Node *value); Entity *caster_get(); void caster_set(Entity *value); void caster_set_bind(Node *value); NodePath caster_get_path(); void caster_set_path(NodePath value); float spell_scale_get(); void spell_scale_set(float value); Ref get_aura(); void set_aura(Ref aura); void refresh(float remaining); int damage_get(); void damage_set(int value); float damage_get_count(); void damage_set_count(int damageTaken); float get_tick(); void set_tick(float value); float get_time_since_last_tick(); void set_time_since_last_tick(float value); int get_unhandled_ticks(); void set_unhandled_ticks(int value); int damage_get_taken(); void damage_set_taken(int value); int heal_get(); void heal_set(int value); int get_remaining_absorb(); void set_remaining_absorb(int remaining_timeAbsorb); float get_slow(); void set_slow(float value); void resolve_references(Node *owner); Dictionary to_dict(); void from_dict(const Dictionary &dict); Dictionary _to_dict(); void _from_dict(const Dictionary &dict); Array to_send_array(); void from_send_array(const Array &arr); Array _to_send_array(); void _from_send_array(const Array &arr); AuraData(); protected: static void _bind_methods(); private: Entity *_owner; int _aura_id; StringName _aura_path; float _remaining_time; Entity *_caster; NodePath _caster_path; float _spell_scale; int _aura_group; Ref _aura; bool _is_timed; int _damage; int _heal; float _slow; int _remaining_absorb; float _tick; float _time_since_last_tick; int _damage_already_taken; int _unhandled_ticks; }; #endif ================================================ FILE: entities/data/character_spec.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "character_spec.h" #include "../../data/spells/spell.h" #include "../../defines.h" int CharacterSpec::get_id() const { return _id; } void CharacterSpec::set_id(const int value) { _id = value; } int CharacterSpec::get_num_rows() const { return _rows.size(); } void CharacterSpec::set_num_rows(const int value) { _rows.resize(value); } int CharacterSpec::get_num_columns(const int row) const { ERR_FAIL_INDEX_V(row, _rows.size(), 0); return _rows[row].size(); } void CharacterSpec::set_num_columns(const int row, const int value) { ERR_FAIL_INDEX(row, _rows.size()); _rows.write[row].resize(value); } int CharacterSpec::get_num_ranks(const int row, const int column) const { ERR_FAIL_INDEX_V(row, _rows.size(), 0); ERR_FAIL_INDEX_V(column, _rows[row].size(), 0); return _rows[row][column].size(); } void CharacterSpec::set_num_ranks(const int row, const int column, const int value) { ERR_FAIL_INDEX(row, _rows.size()); _rows.write[row].write[column].resize(value); } Vector CharacterSpec::get_talents() { Vector r; for (int i = 0; i < _rows.size(); i++) { Vector col; for (int j = 0; j < _rows[i].size(); j++) { Vector entries; for (int k = 0; k < _rows[j].size(); k++) { #if GODOT4 entries.push_back(_rows[i][j][k]); #else entries.push_back(_rows[i][j][k].get_ref_ptr()); #endif } col.push_back(entries); } r.push_back(col); } return r; } Ref CharacterSpec::get_talent(const int row, const int column, const int rank) { ERR_FAIL_INDEX_V(row, _rows.size(), Ref()); ERR_FAIL_INDEX_V(column, _rows[row].size(), Ref()); ERR_FAIL_INDEX_V(rank, _rows[row][column].size(), Ref()); return _rows[row][column][rank]; } void CharacterSpec::set_talent(const int row, const int column, const int rank, const Ref &talent) { ERR_FAIL_INDEX(row, _rows.size()); ERR_FAIL_INDEX(column, _rows[row].size()); ERR_FAIL_INDEX(rank, _rows[row][column].size()); _rows.write[row].write[column].write[rank] = talent; } bool CharacterSpec::has_talent_with_id(const int id) { for (int i = 0; i < _rows.size(); ++i) { for (int j = 0; j < _rows[i].size(); ++j) { for (int k = 0; k < _rows[i][j].size(); ++k) { const Ref a = _rows[i][j][k]; if (a.is_valid() && a->get_id() == id) return true; } } } return false; } Ref CharacterSpec::get_talent_with_id(const int id) { for (int i = 0; i < _rows.size(); ++i) { for (int j = 0; j < _rows[i].size(); ++j) { for (int k = 0; k < _rows[i][j].size(); ++k) { const Ref a = _rows[i][j][k]; if (a.is_valid() && a->get_id() == id) return a; } } } return Ref(); } CharacterSpec::CharacterSpec() { _id = 0; } CharacterSpec::~CharacterSpec() { for (int i = 0; i < _rows.size(); ++i) { for (int j = 0; j < _rows[i].size(); ++j) { for (int k = 0; k < _rows[i][j].size(); ++k) { _rows.write[i].write[j].write[k].unref(); } } } _rows.clear(); } bool CharacterSpec::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; if (name.begins_with("row_")) { String nprop = name.get_slicec('/', 0); //row_[] int row_id = nprop.get_slicec('_', 1).to_int(); if (row_id >= _rows.size()) { _rows.resize(row_id + 1); } String cprop = name.get_slicec('/', 1); //column_[] or size if (cprop == "size") { _rows.write[row_id].resize(p_value); return true; } else { int col_id = cprop.get_slicec('_', 1).to_int(); if (col_id >= _rows[row_id].size()) { _rows.write[row_id].resize(col_id + 1); } String eprop = name.get_slicec('/', 2); //entry_[] or size if (eprop == "size") { _rows.write[row_id].write[col_id].resize(p_value); return true; } else { int entry_id = eprop.get_slicec('_', 1).to_int(); if (entry_id >= _rows[row_id][col_id].size()) { _rows.write[row_id].write[col_id].resize(col_id + 1); } _rows.write[row_id].write[col_id].write[entry_id] = p_value; return true; } } } return false; } bool CharacterSpec::_get(const StringName &p_name, Variant &r_ret) const { String name = p_name; if (name.begins_with("row_")) { String nprop = name.get_slicec('/', 0); //row_[] int row_id = nprop.get_slicec('_', 1).to_int(); if (row_id >= _rows.size()) { return false; } String cprop = name.get_slicec('/', 1); //column_[] or size if (cprop == "size") { r_ret = _rows[row_id].size(); return true; } else { int col_id = cprop.get_slicec('_', 1).to_int(); if (col_id >= _rows[row_id].size()) { return false; } String eprop = name.get_slicec('/', 2); //entry_[] or size if (eprop == "size") { r_ret = _rows[row_id][col_id].size(); return true; } else { int entry_id = eprop.get_slicec('_', 1).to_int(); if (entry_id >= _rows[row_id][col_id].size()) { return false; } r_ret = _rows[row_id][col_id][entry_id]; return true; } } } else { return false; } return false; } void CharacterSpec::_get_property_list(List *p_list) const { for (int i = 0; i < _rows.size(); ++i) { p_list->push_back(PropertyInfo(Variant::INT, "row_" + itos(i) + "/size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED)); for (int j = 0; j < _rows[i].size(); ++j) { p_list->push_back(PropertyInfo(Variant::INT, "row_" + itos(i) + "/column_" + itos(j) + "/size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED)); for (int k = 0; k < _rows[i][j].size(); ++k) { p_list->push_back(PropertyInfo(Variant::OBJECT, "row_" + itos(i) + "/column_" + itos(j) + "/entry_" + itos(k), PROPERTY_HINT_RESOURCE_TYPE, "Spell", PROPERTY_USAGE_DEFAULT)); } } } } void CharacterSpec::_bind_methods() { ClassDB::bind_method(D_METHOD("get_id"), &CharacterSpec::get_id); ClassDB::bind_method(D_METHOD("set_id", "value"), &CharacterSpec::set_id); ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text_name"), "set_name", "get_name"); ClassDB::bind_method(D_METHOD("get_num_rows"), &CharacterSpec::get_num_rows); ClassDB::bind_method(D_METHOD("set_num_rows", "value"), &CharacterSpec::set_num_rows); ADD_PROPERTY(PropertyInfo(Variant::INT, "num_rows", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_num_rows", "get_num_rows"); ClassDB::bind_method(D_METHOD("get_num_columns", "row"), &CharacterSpec::get_num_columns); ClassDB::bind_method(D_METHOD("set_num_columns", "row", "value"), &CharacterSpec::set_num_columns); ClassDB::bind_method(D_METHOD("get_num_ranks", "row", "culomn"), &CharacterSpec::get_num_ranks); ClassDB::bind_method(D_METHOD("set_num_ranks", "row", "culomn", "value"), &CharacterSpec::set_num_ranks); ClassDB::bind_method(D_METHOD("get_talents"), &CharacterSpec::get_talents); ClassDB::bind_method(D_METHOD("get_talent", "row", "culomn", "rank"), &CharacterSpec::get_talent); ClassDB::bind_method(D_METHOD("set_talent", "row", "culomn", "rank"), &CharacterSpec::set_talent); ClassDB::bind_method(D_METHOD("has_talent_with_id", "id"), &CharacterSpec::has_talent_with_id); ClassDB::bind_method(D_METHOD("get_talent_with_id", "id"), &CharacterSpec::get_talent_with_id); } ================================================ FILE: entities/data/character_spec.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef CHARACTER_SPEC_H #define CHARACTER_SPEC_H #include "core/version.h" #include "core/io/resource.h" #include "core/templates/vector.h" #include "core/string/ustring.h" class Spell; class CharacterSpec : public Resource { GDCLASS(CharacterSpec, Resource); public: int get_id() const; void set_id(const int value); int get_num_rows() const; void set_num_rows(const int value); int get_num_columns(const int row) const; void set_num_columns(const int row, const int value); int get_num_ranks(const int row, const int column) const; void set_num_ranks(const int row, const int column, const int value); Vector get_talents(); Ref get_talent(const int row, const int column, const int rank); void set_talent(const int row, const int column, const int rank, const Ref &talent); bool has_talent_with_id(const int id); Ref get_talent_with_id(const int id); CharacterSpec(); ~CharacterSpec(); protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List *p_list) const; static void _bind_methods(); private: int _id; Vector > > > _rows; }; #endif ================================================ FILE: entities/data/entity_class_data.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "entity_class_data.h" #include "../../data/items/craft_recipe.h" #include "../../data/items/item_instance.h" #include "../../data/spells/spell.h" #include "../../entities/stats/stat_data.h" #include "../../infos/spell_cast_info.h" #include "../ai/entity_ai.h" #include "../entity.h" #include "character_spec.h" #include "item_container_data.h" #include "vendor_item_data.h" #include "../../defines.h" int EntityClassData::get_id() { return _id; } void EntityClassData::set_id(int value) { _id = value; } String EntityClassData::get_text_description() { return _text_description; } void EntityClassData::set_text_description(String value) { _text_description = value; } Ref EntityClassData::get_icon() { return _icon; } void EntityClassData::set_icon(Ref value) { _icon = Ref(value); } int EntityClassData::get_spell_points_per_level() { return _spell_points_per_level; } void EntityClassData::set_spell_points_per_level(int value) { _spell_points_per_level = value; } EntityEnums::EntityClassPlaystyleType EntityClassData::get_playstyle_type() { return _playstyle_type; } void EntityClassData::set_playstyle_type(EntityEnums::EntityClassPlaystyleType playstyle_type) { _playstyle_type = playstyle_type; } Ref EntityClassData::get_stat_data() { return _stat_data; } void EntityClassData::set_stat_data(Ref value) { _stat_data = value; } //// Entity Resources //// int EntityClassData::get_num_entity_resources() { return _entity_resources.size(); } void EntityClassData::set_num_entity_resources(int value) { _entity_resources.resize(value); } Ref EntityClassData::get_entity_resource(int index) const { ERR_FAIL_INDEX_V(index, _entity_resources.size(), Ref()); return _entity_resources[index]; } void EntityClassData::set_entity_resource(int index, Ref entity_resource) { ERR_FAIL_INDEX(index, _entity_resources.size()); _entity_resources.set(index, Ref(entity_resource)); } Vector EntityClassData::get_entity_resources() { VARIANT_ARRAY_GET(_entity_resources); } void EntityClassData::set_entity_resources(const Vector &entity_resources) { _entity_resources.clear(); for (int i = 0; i < entity_resources.size(); i++) { Ref entity_resource = Ref(entity_resources[i]); _entity_resources.push_back(entity_resource); } } //// SPECS //// int EntityClassData::get_num_specs() { return _specs.size(); } void EntityClassData::set_num_specs(int value) { _specs.resize(value); } Ref EntityClassData::get_spec(int index) const { ERR_FAIL_INDEX_V(index, _specs.size(), Ref()); return _specs[index]; } void EntityClassData::set_spec(int index, Ref spec) { ERR_FAIL_INDEX(index, _specs.size()); _specs.set(index, Ref(spec)); } Vector EntityClassData::get_specs() { VARIANT_ARRAY_GET(_specs); } void EntityClassData::set_specs(const Vector &specs) { _specs.clear(); for (int i = 0; i < specs.size(); i++) { Ref spec = Ref(specs[i]); _specs.push_back(spec); } } //// SPELLS //// int EntityClassData::get_num_spells() { return _spells.size(); } void EntityClassData::set_num_spells(int value) { _spells.resize(value); } Ref EntityClassData::get_spell(int index) { ERR_FAIL_INDEX_V(index, _spells.size(), Ref()); return _spells[index]; } void EntityClassData::set_spell(int index, Ref spell) { ERR_FAIL_INDEX(index, _spells.size()); _spells.set(index, Ref(spell)); } Vector EntityClassData::get_spells() { VARIANT_ARRAY_GET(_spells); } void EntityClassData::set_spells(const Vector &spells) { _spells.clear(); for (int i = 0; i < spells.size(); i++) { Ref spell = Ref(spells[i]); _spells.push_back(spell); } } //// Start Spells //// int EntityClassData::get_num_start_spells() { return _start_spells.size(); } void EntityClassData::set_num_start_spells(int value) { _start_spells.resize(value); } Ref EntityClassData::get_start_spell(int index) { ERR_FAIL_INDEX_V(index, _start_spells.size(), Ref()); return _start_spells[index]; } void EntityClassData::set_start_spell(int index, Ref spell) { ERR_FAIL_INDEX(index, _start_spells.size()); _start_spells.set(index, Ref(spell)); } Vector EntityClassData::get_start_spells() { VARIANT_ARRAY_GET(_start_spells); } void EntityClassData::set_start_spells(const Vector &spells) { _start_spells.clear(); for (int i = 0; i < spells.size(); i++) { Ref spell = Ref(spells[i]); _start_spells.push_back(spell); } } //// AURAS //// int EntityClassData::get_num_auras() { return _auras.size(); } void EntityClassData::set_num_auras(int value) { _auras.resize(value); } Ref EntityClassData::get_aura(int index) { ERR_FAIL_INDEX_V(index, _auras.size(), Ref()); return _auras[index]; } void EntityClassData::set_aura(int index, Ref aura) { ERR_FAIL_INDEX(index, _auras.size()); _auras.set(index, aura); } Vector EntityClassData::get_auras() { VARIANT_ARRAY_GET(_auras); } void EntityClassData::set_auras(const Vector &auras) { _auras.clear(); for (int i = 0; i < auras.size(); i++) { Ref aura = Ref(auras[i]); _auras.push_back(aura); } } Ref EntityClassData::get_vendor_item_data() const { return _vendor_item_data; } void EntityClassData::set_vendor_item_data(const Ref &data) { _vendor_item_data = data; } Ref EntityClassData::get_spell_train_data() const { return _spell_train_data; } void EntityClassData::set_spell_train_data(const Ref &data) { _spell_train_data = data; } Ref EntityClassData::get_item_container_data() const { return _item_container_data; } void EntityClassData::set_item_container_data(const Ref &data) { _item_container_data = data; } //Craft Recipes int EntityClassData::get_num_craft_recipes() const { return _craft_recipes.size(); } Ref EntityClassData::get_craft_recipe(int index) { ERR_FAIL_INDEX_V(index, _craft_recipes.size(), Ref()); return _craft_recipes[index]; } void EntityClassData::set_craft_recipe(int index, const Ref &craft_data) { ERR_FAIL_INDEX(index, _craft_recipes.size()); _craft_recipes.set(index, craft_data); } Vector EntityClassData::get_craft_recipes() const { VARIANT_ARRAY_GET(_craft_recipes); } void EntityClassData::set_craft_recipes(const Vector &craft_datas) { _craft_recipes.clear(); for (int i = 0; i < craft_datas.size(); i++) { Ref craft_data = Ref(craft_datas[i]); _craft_recipes.push_back(craft_data); } } //// AI ACTIONS //// int EntityClassData::get_num_ais() { return _ais.size(); } void EntityClassData::set_num_ais(int value) { _ais.resize(value); } Ref EntityClassData::get_ai(int index) { ERR_FAIL_INDEX_V(index, _ais.size(), Ref()); return _ais[index]; } void EntityClassData::set_ai(int index, Ref ai) { ERR_FAIL_INDEX(index, _ais.size()); _ais.set(index, ai); } Vector EntityClassData::get_ais() { VARIANT_ARRAY_GET(_ais); } void EntityClassData::set_ais(const Vector &ais) { _ais.clear(); for (int i = 0; i < ais.size(); i++) { Ref ai = Ref(ais[i]); _ais.push_back(ai); } } Ref EntityClassData::get_ai_instance() { return call("_get_ai_instance"); } Ref EntityClassData::_get_ai_instance() { if (_ais.size() > 0) { Ref ai = _ais.get(Math::rand() % _ais.size()); if (ai.is_valid()) { return ai->duplicate(); } } Ref ai; ai.instantiate(); return ai; } //// SETUP //// void EntityClassData::setup_resources(Entity *entity) { call("_setup_resources", entity); } void EntityClassData::_setup_resources(Node *entity) { Entity *ent = Object::cast_to(entity); for (int i = 0; i < _entity_resources.size(); ++i) { Ref res = _entity_resources.get(i); if (res.is_valid()) { Ref r = res->duplicate(); ent->resource_adds(r); } } } EntityClassData::EntityClassData() { _id = 0; _spell_points_per_level = 1; _playstyle_type = EntityEnums::ENTITY_CLASS_PLAYSTYLE_TYPE_MELEE; } EntityClassData::~EntityClassData() { _stat_data.unref(); _spells.clear(); _specs.clear(); _auras.clear(); _vendor_item_data.unref(); _spell_train_data.unref(); _item_container_data.unref(); _craft_recipes.clear(); _ais.clear(); } void EntityClassData::_bind_methods() { //GDVIRTUAL_BIND("_setup_resources", "entity", "Entity"); ClassDB::bind_method(D_METHOD("get_id"), &EntityClassData::get_id); ClassDB::bind_method(D_METHOD("set_id", "value"), &EntityClassData::set_id); ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text_name"), "set_name", "get_name"); ClassDB::bind_method(D_METHOD("get_text_description"), &EntityClassData::get_text_description); ClassDB::bind_method(D_METHOD("set_text_description", "value"), &EntityClassData::set_text_description); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text_description"), "set_text_description", "get_text_description"); ClassDB::bind_method(D_METHOD("get_icon"), &EntityClassData::get_icon); ClassDB::bind_method(D_METHOD("set_icon", "value"), &EntityClassData::set_icon); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_icon", "get_icon"); ClassDB::bind_method(D_METHOD("get_spell_points_per_level"), &EntityClassData::get_spell_points_per_level); ClassDB::bind_method(D_METHOD("set_spell_points_per_level", "value"), &EntityClassData::set_spell_points_per_level); ADD_PROPERTY(PropertyInfo(Variant::INT, "spell_points_per_level"), "set_spell_points_per_level", "get_spell_points_per_level"); ClassDB::bind_method(D_METHOD("get_playstyle_type"), &EntityClassData::get_playstyle_type); ClassDB::bind_method(D_METHOD("set_playstyle_type", "value"), &EntityClassData::set_playstyle_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "playstyle_type", PROPERTY_HINT_ENUM, EntityEnums::BINDING_STRING_ENTITY_PLAYSTYLE_TYPE), "set_playstyle_type", "get_playstyle_type"); ClassDB::bind_method(D_METHOD("get_stat_data"), &EntityClassData::get_stat_data); ClassDB::bind_method(D_METHOD("set_stat_data", "value"), &EntityClassData::set_stat_data); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stat_data", PROPERTY_HINT_RESOURCE_TYPE, "StatData"), "set_stat_data", "get_stat_data"); //// Entity Resources //// ClassDB::bind_method(D_METHOD("get_num_entity_resources"), &EntityClassData::get_num_entity_resources); ClassDB::bind_method(D_METHOD("set_num_entity_resources", "value"), &EntityClassData::set_num_entity_resources); ClassDB::bind_method(D_METHOD("get_entity_resource", "index"), &EntityClassData::get_entity_resource); ClassDB::bind_method(D_METHOD("set_entity_resource", "index", "entity_resource"), &EntityClassData::set_entity_resource); ClassDB::bind_method(D_METHOD("get_entity_resources"), &EntityClassData::get_entity_resources); ClassDB::bind_method(D_METHOD("set_entity_resources", "entity_resources"), &EntityClassData::set_entity_resources); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "entity_resources", PROPERTY_HINT_NONE, "17/17:EntityResource", PROPERTY_USAGE_DEFAULT, "EntityResource"), "set_entity_resources", "get_entity_resources"); ClassDB::bind_method(D_METHOD("_setup_resources", "entity"), &EntityClassData::_setup_resources); //// Specs //// ClassDB::bind_method(D_METHOD("get_num_specs"), &EntityClassData::get_num_specs); ClassDB::bind_method(D_METHOD("set_num_specs", "value"), &EntityClassData::set_num_specs); ClassDB::bind_method(D_METHOD("get_spec", "index"), &EntityClassData::get_spec); ClassDB::bind_method(D_METHOD("set_spec", "index", "spec"), &EntityClassData::set_spec); ClassDB::bind_method(D_METHOD("get_specs"), &EntityClassData::get_specs); ClassDB::bind_method(D_METHOD("set_specs", "specs"), &EntityClassData::set_specs); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "specs", PROPERTY_HINT_NONE, "17/17:CharacterSpec", PROPERTY_USAGE_DEFAULT, "CharacterSpec"), "set_specs", "get_specs"); //// Spell //// ClassDB::bind_method(D_METHOD("get_num_spells"), &EntityClassData::get_num_spells); ClassDB::bind_method(D_METHOD("set_num_spells", "value"), &EntityClassData::set_num_spells); ClassDB::bind_method(D_METHOD("get_spell", "index"), &EntityClassData::get_spell); ClassDB::bind_method(D_METHOD("set_spell", "index", "spell"), &EntityClassData::set_spell); ClassDB::bind_method(D_METHOD("get_spells"), &EntityClassData::get_spells); ClassDB::bind_method(D_METHOD("set_spells", "spells"), &EntityClassData::set_spells); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "spells", PROPERTY_HINT_NONE, "17/17:Spell", PROPERTY_USAGE_DEFAULT, "Spell"), "set_spells", "get_spells"); //// Start Spells //// ClassDB::bind_method(D_METHOD("get_num_start_spells"), &EntityClassData::get_num_start_spells); ClassDB::bind_method(D_METHOD("set_num_start_spells", "value"), &EntityClassData::set_num_start_spells); ClassDB::bind_method(D_METHOD("get_start_spell", "index"), &EntityClassData::get_start_spell); ClassDB::bind_method(D_METHOD("set_start_spell", "index", "spell"), &EntityClassData::set_start_spell); ClassDB::bind_method(D_METHOD("get_start_spells"), &EntityClassData::get_start_spells); ClassDB::bind_method(D_METHOD("set_start_spells", "spells"), &EntityClassData::set_start_spells); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "start_spells", PROPERTY_HINT_NONE, "17/17:Spell", PROPERTY_USAGE_DEFAULT, "Spell"), "set_start_spells", "get_start_spells"); //// AURAS //// ClassDB::bind_method(D_METHOD("get_num_auras"), &EntityClassData::get_num_auras); ClassDB::bind_method(D_METHOD("set_num_auras", "value"), &EntityClassData::set_num_auras); ClassDB::bind_method(D_METHOD("get_aura", "index"), &EntityClassData::get_aura); ClassDB::bind_method(D_METHOD("set_aura", "index", "aura"), &EntityClassData::set_aura); ClassDB::bind_method(D_METHOD("get_auras"), &EntityClassData::get_auras); ClassDB::bind_method(D_METHOD("set_auras", "auras"), &EntityClassData::set_auras); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "auras", PROPERTY_HINT_NONE, "17/17:Spell", PROPERTY_USAGE_DEFAULT, "Spell"), "set_auras", "get_auras"); //Vendor ClassDB::bind_method(D_METHOD("get_vendor_item_data"), &EntityClassData::get_vendor_item_data); ClassDB::bind_method(D_METHOD("set_vendor_item_data", "value"), &EntityClassData::set_vendor_item_data); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "vendor_item_data", PROPERTY_HINT_RESOURCE_TYPE, "VendorItemData"), "set_vendor_item_data", "get_vendor_item_data"); ClassDB::bind_method(D_METHOD("get_spell_train_data"), &EntityClassData::get_spell_train_data); ClassDB::bind_method(D_METHOD("set_spell_train_data", "value"), &EntityClassData::set_spell_train_data); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "spell_train_data", PROPERTY_HINT_RESOURCE_TYPE, "VendorItemData"), "set_spell_train_data", "get_spell_train_data"); //ItemContainerData ClassDB::bind_method(D_METHOD("get_item_container_data"), &EntityClassData::get_item_container_data); ClassDB::bind_method(D_METHOD("set_item_container_data", "value"), &EntityClassData::set_item_container_data); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "item_container_data", PROPERTY_HINT_RESOURCE_TYPE, "ItemContainerData"), "set_item_container_data", "get_item_container_data"); //Crafting ClassDB::bind_method(D_METHOD("get_num_craft_recipes"), &EntityClassData::get_num_craft_recipes); ClassDB::bind_method(D_METHOD("get_craft_recipe", "index"), &EntityClassData::get_craft_recipe); ClassDB::bind_method(D_METHOD("set_craft_recipe", "index", "recipe"), &EntityClassData::set_craft_recipe); ClassDB::bind_method(D_METHOD("get_craft_recipes"), &EntityClassData::get_craft_recipes); ClassDB::bind_method(D_METHOD("set_craft_recipes", "recipe"), &EntityClassData::set_craft_recipes); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "craft_recipes", PROPERTY_HINT_NONE, "17/17:CraftRecipe", PROPERTY_USAGE_DEFAULT, "CraftRecipe"), "set_craft_recipes", "get_craft_recipes"); //// AI ACTIONS //// ClassDB::bind_method(D_METHOD("get_num_ais"), &EntityClassData::get_num_ais); ClassDB::bind_method(D_METHOD("set_num_ais", "value"), &EntityClassData::set_num_ais); ClassDB::bind_method(D_METHOD("get_ai", "index"), &EntityClassData::get_ai); ClassDB::bind_method(D_METHOD("set_ai", "index", "action"), &EntityClassData::set_ai); ClassDB::bind_method(D_METHOD("get_ais"), &EntityClassData::get_ais); ClassDB::bind_method(D_METHOD("set_ais", "auras"), &EntityClassData::set_ais); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "ais", PROPERTY_HINT_NONE, "17/17:EntityAI", PROPERTY_USAGE_DEFAULT, "EntityAI"), "set_ais", "get_ais"); //GDVIRTUAL_BIND("_get_ai_instance"); ClassDB::bind_method(D_METHOD("get_ai_instance"), &EntityClassData::get_ai_instance); ClassDB::bind_method(D_METHOD("_get_ai_instance"), &EntityClassData::_get_ai_instance); } ================================================ FILE: entities/data/entity_class_data.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef ENTITY_CLASS_DATA_H #define ENTITY_CLASS_DATA_H #include "core/version.h" #include "core/io/resource.h" #include "core/templates/vector.h" #include "core/string/ustring.h" #include "core/math/math_funcs.h" #include "scene/resources/texture.h" #include "../../entities/stats/stat_data.h" #include "../../entity_enums.h" #include "../../entities/auras/aura_data.h" #include "../../pipelines/spell_damage_info.h" #include "../../pipelines/spell_heal_info.h" #include "../../item_enums.h" #include "../resources/entity_resource.h" class Spell; class Entity; class ItemInstance; class CharacterSpec; class Entity; class SpellCastInfo; class EntityAI; class VendorItemData; class ItemContainerData; class CraftRecipe; class StatData; class EntityClassData : public Resource { GDCLASS(EntityClassData, Resource); public: int get_id(); void set_id(int value); String get_text_description(); void set_text_description(String value); Ref get_icon(); void set_icon(Ref value); int get_spell_points_per_level(); void set_spell_points_per_level(int value); EntityEnums::EntityClassPlaystyleType get_playstyle_type(); void set_playstyle_type(EntityEnums::EntityClassPlaystyleType playstyle_type); Ref get_stat_data(); void set_stat_data(Ref value); //Entity Resources int get_num_entity_resources(); void set_num_entity_resources(int value); Ref get_entity_resource(int index) const; void set_entity_resource(int index, Ref entity_resources); Vector get_entity_resources(); void set_entity_resources(const Vector &entity_resourcess); //Specs int get_num_specs(); void set_num_specs(int value); Ref get_spec(int index) const; void set_spec(int index, Ref spec); Vector get_specs(); void set_specs(const Vector &specs); //Spells int get_num_spells(); void set_num_spells(int value); Ref get_spell(int index); void set_spell(int index, Ref spell); Vector get_spells(); void set_spells(const Vector &spells); //Start Spells int get_num_start_spells(); void set_num_start_spells(int value); Ref get_start_spell(int index); void set_start_spell(int index, Ref spell); Vector get_start_spells(); void set_start_spells(const Vector &spells); //Auras int get_num_auras(); void set_num_auras(int value); Ref get_aura(int index); void set_aura(int index, Ref aura); Vector get_auras(); void set_auras(const Vector &auras); //Data Ref get_vendor_item_data() const; void set_vendor_item_data(const Ref &data); Ref get_spell_train_data() const; void set_spell_train_data(const Ref &data); Ref get_item_container_data() const; void set_item_container_data(const Ref &data); //Craft Recipes int get_num_craft_recipes() const; Ref get_craft_recipe(int index); void set_craft_recipe(int index, const Ref &recipe); Vector get_craft_recipes() const; void set_craft_recipes(const Vector &recipe); //AI int get_num_ais(); void set_num_ais(int value); Ref get_ai(int index); void set_ai(int index, Ref aura); Vector get_ais(); void set_ais(const Vector &ais); Ref get_ai_instance(); Ref _get_ai_instance(); //Setup void setup_resources(Entity *entity); void _setup_resources(Node *entity); EntityClassData(); ~EntityClassData(); protected: static void _bind_methods(); private: int _id; String _text_description; Ref _icon; int _spell_points_per_level; EntityEnums::EntityClassPlaystyleType _playstyle_type; Ref _stat_data; Vector > _entity_resources; Vector > _specs; Vector > _spells; Vector > _start_spells; Vector > _auras; Ref _vendor_item_data; Ref _spell_train_data; Ref _item_container_data; Vector > _craft_recipes; Vector > _ais; }; #endif ================================================ FILE: entities/data/entity_data.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "entity_data.h" #include "../../data/spells/spell.h" #include "../../infos/spell_cast_info.h" #include "../entity.h" #include "character_spec.h" #include "../../data/species/entity_species_data.h" #include "../../data/species/species_instance.h" #include "../../singletons/ess.h" #include "../../defines.h" int EntityData::get_id() const { return _id; } void EntityData::set_id(int value) { _id = value; } String EntityData::get_text_description() const { return _text_description; } void EntityData::set_text_description(String value) { _text_description = value; } EntityEnums::EntityInteractionType EntityData::get_entity_interaction_type() const { return _interaction_type; } void EntityData::set_entity_interaction_type(EntityEnums::EntityInteractionType value) { _interaction_type = value; } bool EntityData::get_is_playable() const { return _is_playable; } void EntityData::set_is_playable(const bool value) { _is_playable = value; } int EntityData::get_immunity_flags() const { return _immunity_flags; } void EntityData::set_immunity_flags(const int value) { _immunity_flags = value; } int EntityData::get_entity_flags() const { return _entity_flags; } void EntityData::set_entity_flags(const int value) { _entity_flags = value; } int EntityData::get_money() const { return _money; } void EntityData::set_money(const int value) { _money = value; } int EntityData::get_bag_size() const { return _bag_size; } void EntityData::set_bag_size(const int value) { _bag_size = value; } Ref EntityData::get_entity_species_data() const { return _entity_species_data; } void EntityData::set_entity_species_data(const Ref &value) { _entity_species_data = value; } Ref EntityData::get_entity_class_data() const { return _entity_class_data; } void EntityData::set_entity_class_data(const Ref &data) { _entity_class_data = data; } Ref EntityData::get_equipment_data() const { return _equipment_data; } void EntityData::set_equipment_data(const Ref &data) { _equipment_data = data; } Ref EntityData::get_species_instance() const { return _species_instance; } void EntityData::set_species_instance(const Ref &value) { _species_instance = value; } Ref EntityData::get_ai() const { return _ai; } void EntityData::set_ai(const Ref &ai) { _ai = ai; } Ref EntityData::get_ai_instance() { return call("_get_ai_instance"); } Ref EntityData::_get_ai_instance() { if (_ai.is_valid()) { return _ai->duplicate(); } Ref ecd = get_entity_class_data(); if (ecd.is_valid()) { return ecd->get_ai_instance(); } Ref ai; ai.instantiate(); return ai; } Ref EntityData::get_loot_db() const { return _lootdb; } void EntityData::set_loot_db(const Ref &lootdb) { _lootdb = lootdb; } //void EntityData::_setup_resources(Entity *entity) { //} /* Vector EntityData::get_mob_party_ids() { return _mob_party_ids; } void EntityData::set_mob_party_ids(Vector ids) { //specs; } Vector EntityData::get_mob_dislike_ids() { return _mob_dislike_ids; } void EntityData::set_mob_dislike_ids(Vector ids) { //specs; } */ /* int EntityData::get_inspector_max_spells() { return _inspector_max_spells; } void EntityData::set_inspector_max_spells(int value) { _inspector_max_spells = value; }*/ String EntityData::generate_name() { if (has_method("_generate_name")) { return call("_generate_name"); } return get_name(); } //// SETUP //// void EntityData::setup_resources(Entity *entity) { ERR_FAIL_COND(!INSTANCE_VALIDATE(entity)); if (_entity_class_data.is_valid()) _entity_class_data->setup_resources(entity); if (has_method("_setup_resources")) call("_setup_resources", entity); } bool EntityData::cans_interact(Entity *entity) { ERR_FAIL_COND_V(!INSTANCE_VALIDATE(entity), false); if (has_method("_cans_interact")) return call("_cans_interact", entity); return false; } bool EntityData::cans_interact_bind(Node *entity) { ERR_FAIL_COND_V(!INSTANCE_VALIDATE(entity), false); Entity *e = Object::cast_to(entity); ERR_FAIL_COND_V(e == NULL, false); return cans_interact(e); } void EntityData::sinteract(Entity *entity) { ERR_FAIL_COND(!INSTANCE_VALIDATE(entity)); if (has_method("_sinteract")) call("_sinteract", entity); } void EntityData::sinteract_bind(Node *entity) { ERR_FAIL_COND(!INSTANCE_VALIDATE(entity)); Entity *e = Object::cast_to(entity); ERR_FAIL_COND(e == NULL); sinteract(e); } EntityData::EntityData() { _id = 0; _money = 0; _bag_size = 0; _is_playable = false; _interaction_type = EntityEnums::ENITIY_INTERACTION_TYPE_NORMAL; _immunity_flags = 0; _entity_flags = 0; } EntityData::~EntityData() { _entity_class_data.unref(); _entity_species_data.unref(); _equipment_data.unref(); _species_instance.unref(); _ai.unref(); _lootdb.unref(); } void EntityData::_validate_property(PropertyInfo &property) const { if (property.name == "entity_type") { property.hint_string = ESS::get_singleton()->entity_types_get(); } } void EntityData::_bind_methods() { //Interactions //GDVIRTUAL_BIND("_cans_interact", "entity", "Entity"); //GDVIRTUAL_BIND("_sinteract", "entity", "Entity"); ClassDB::bind_method(D_METHOD("cans_interact", "entity"), &EntityData::cans_interact_bind); ClassDB::bind_method(D_METHOD("sinteract", "entity"), &EntityData::sinteract_bind); ClassDB::bind_method(D_METHOD("get_id"), &EntityData::get_id); ClassDB::bind_method(D_METHOD("set_id", "value"), &EntityData::set_id); ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id"); ClassDB::bind_method(D_METHOD("get_entity_interaction_type"), &EntityData::get_entity_interaction_type); ClassDB::bind_method(D_METHOD("set_entity_interaction_type", "value"), &EntityData::set_entity_interaction_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "entity_interaction_type", PROPERTY_HINT_ENUM, EntityEnums::BINDING_STRING_ENTITY_INTERACTION_TYPE), "set_entity_interaction_type", "get_entity_interaction_type"); ClassDB::bind_method(D_METHOD("get_is_playable"), &EntityData::get_is_playable); ClassDB::bind_method(D_METHOD("set_is_playable", "value"), &EntityData::set_is_playable); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_playable"), "set_is_playable", "get_is_playable"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text_name"), "set_name", "get_name"); ClassDB::bind_method(D_METHOD("get_text_description"), &EntityData::get_text_description); ClassDB::bind_method(D_METHOD("set_text_description", "value"), &EntityData::set_text_description); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text_description"), "set_text_description", "get_text_description"); ClassDB::bind_method(D_METHOD("get_money"), &EntityData::get_money); ClassDB::bind_method(D_METHOD("set_money", "value"), &EntityData::set_money); ADD_PROPERTY(PropertyInfo(Variant::INT, "money"), "set_money", "get_money"); ClassDB::bind_method(D_METHOD("get_bag_size"), &EntityData::get_bag_size); ClassDB::bind_method(D_METHOD("set_bag_size", "value"), &EntityData::set_bag_size); ADD_PROPERTY(PropertyInfo(Variant::INT, "bag_size"), "set_bag_size", "get_bag_size"); ClassDB::bind_method(D_METHOD("get_entity_species_data"), &EntityData::get_entity_species_data); ClassDB::bind_method(D_METHOD("set_entity_species_data", "value"), &EntityData::set_entity_species_data); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "entity_species_data", PROPERTY_HINT_RESOURCE_TYPE, "EntitySpeciesData"), "set_entity_species_data", "get_entity_species_data"); ClassDB::bind_method(D_METHOD("get_entity_class_data"), &EntityData::get_entity_class_data); ClassDB::bind_method(D_METHOD("set_entity_class_data", "value"), &EntityData::set_entity_class_data); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "entity_class_data", PROPERTY_HINT_RESOURCE_TYPE, "EntityClassData"), "set_entity_class_data", "get_entity_class_data"); ClassDB::bind_method(D_METHOD("get_equipment_data"), &EntityData::get_equipment_data); ClassDB::bind_method(D_METHOD("set_equipment_data", "value"), &EntityData::set_equipment_data); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "equipment_data", PROPERTY_HINT_RESOURCE_TYPE, "EquipmentData"), "set_equipment_data", "get_equipment_data"); ClassDB::bind_method(D_METHOD("get_species_instance"), &EntityData::get_species_instance); ClassDB::bind_method(D_METHOD("set_species_instance", "value"), &EntityData::set_species_instance); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "species_instance", PROPERTY_HINT_RESOURCE_TYPE, "SpeciesInstance"), "set_species_instance", "get_species_instance"); //AI //GDVIRTUAL_BIND("_get_ai_instance"); ClassDB::bind_method(D_METHOD("get_ai"), &EntityData::get_ai); ClassDB::bind_method(D_METHOD("set_ai", "value"), &EntityData::set_ai); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "ai", PROPERTY_HINT_RESOURCE_TYPE, "EntityAI"), "set_ai", "get_ai"); ClassDB::bind_method(D_METHOD("get_ai_instance"), &EntityData::get_ai_instance); ClassDB::bind_method(D_METHOD("_get_ai_instance"), &EntityData::_get_ai_instance); // Loot DB ClassDB::bind_method(D_METHOD("get_loot_db"), &EntityData::get_loot_db); ClassDB::bind_method(D_METHOD("set_loot_db", "value"), &EntityData::set_loot_db); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "loot_db", PROPERTY_HINT_RESOURCE_TYPE, "LootDataBase"), "set_loot_db", "get_loot_db"); ClassDB::bind_method(D_METHOD("generate_name"), &EntityData::generate_name); //GDVIRTUAL_BIND("_generate_name"); ADD_GROUP("Immunities", "immunity"); ClassDB::bind_method(D_METHOD("get_immunity_flags"), &EntityData::get_immunity_flags); ClassDB::bind_method(D_METHOD("set_immunity_flags", "value"), &EntityData::set_immunity_flags); ADD_PROPERTY(PropertyInfo(Variant::INT, "immunity_flags", PROPERTY_HINT_FLAGS, EntityEnums::BINDING_STRING_ENTITY_IMMUNITY_FLAGS), "set_immunity_flags", "get_immunity_flags"); ADD_GROUP("Entity Flags", "entity_flags"); ClassDB::bind_method(D_METHOD("get_entity_flags"), &EntityData::get_entity_flags); ClassDB::bind_method(D_METHOD("set_entity_flags", "value"), &EntityData::set_entity_flags); ADD_PROPERTY(PropertyInfo(Variant::INT, "entity_flags", PROPERTY_HINT_FLAGS, EntityEnums::BINDING_STRING_ENTITY_FLAGS), "set_entity_flags", "get_entity_flags"); } ================================================ FILE: entities/data/entity_data.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef ENTITY_DATA_H #define ENTITY_DATA_H #include "core/version.h" #include "core/io/resource.h" #include "core/templates/vector.h" #include "core/string/ustring.h" #include "scene/resources/texture.h" #include "../../entity_enums.h" #include "../../entities/auras/aura_data.h" #include "../../pipelines/spell_damage_info.h" #include "../../pipelines/spell_heal_info.h" #include "../../data/loot/loot_data_base.h" #include "entity_class_data.h" #include "../../data/items/equipment_data.h" #include "../ai/entity_ai.h" class Spell; class Entity; class CharacterSpec; class Entity; class SpellCastInfo; class AIAction; class CraftRecipe; class EntitySpeciesData; class SpeciesInstance; class EntityData : public Resource { GDCLASS(EntityData, Resource); public: int get_id() const; void set_id(const int value); String get_text_description() const; void set_text_description(const String value); EntityEnums::EntityInteractionType get_entity_interaction_type() const; void set_entity_interaction_type(const EntityEnums::EntityInteractionType value); bool get_is_playable() const; void set_is_playable(const bool value); int get_immunity_flags() const; void set_immunity_flags(const int value); int get_entity_flags() const; void set_entity_flags(const int value); int get_money() const; void set_money(const int value); int get_bag_size() const; void set_bag_size(const int value); Ref get_entity_species_data() const; void set_entity_species_data(const Ref &value); Ref get_entity_class_data() const; void set_entity_class_data(const Ref &data); Ref get_equipment_data() const; void set_equipment_data(const Ref &data); Ref get_species_instance() const; void set_species_instance(const Ref &value); Ref get_ai() const; void set_ai(const Ref &ai); Ref get_ai_instance(); Ref _get_ai_instance(); Ref get_loot_db() const; void set_loot_db(const Ref &data); String generate_name(); //Setup void setup_resources(Entity *entity); //// Interactions //// bool cans_interact(Entity *entity); bool cans_interact_bind(Node *entity); void sinteract(Entity *entity); void sinteract_bind(Node *entity); EntityData(); ~EntityData(); protected: void _validate_property(PropertyInfo &property) const; static void _bind_methods(); private: int _id; EntityEnums::EntityInteractionType _interaction_type; bool _is_playable; int _immunity_flags; int _entity_flags; String _text_description; int _money; int _bag_size; Ref _entity_class_data; Ref _entity_species_data; Ref _equipment_data; Ref _species_instance; Ref _ai; Ref _lootdb; }; #endif ================================================ FILE: entities/data/entity_data_container.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "entity_data_container.h" #include "core/version.h" Dictionary EntityDataContainer::to_dict() { return call("_to_dict"); } void EntityDataContainer::from_dict(const Dictionary &dict) { call("_from_dict", dict); } Dictionary EntityDataContainer::_to_dict() { Dictionary dict; dict["class_name"] = get_class_static(); return dict; } void EntityDataContainer::_from_dict(const Dictionary &dict) { ERR_FAIL_COND(dict.is_empty()); } EntityDataContainer::EntityDataContainer() { } EntityDataContainer::~EntityDataContainer() { } void EntityDataContainer::_bind_methods() { //Serialization //GDVIRTUAL_BIND("from_dict", "dict"); //GDVIRTUAL_BIND("to_dict", "dict"); ClassDB::bind_method(D_METHOD("from_dict", "dict"), &EntityDataContainer::from_dict); ClassDB::bind_method(D_METHOD("to_dict"), &EntityDataContainer::to_dict); ClassDB::bind_method(D_METHOD("_from_dict", "dict"), &EntityDataContainer::_from_dict); ClassDB::bind_method(D_METHOD("_to_dict"), &EntityDataContainer::_to_dict); } ================================================ FILE: entities/data/entity_data_container.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef ENTITY_DATA_CONTAINER_H #define ENTITY_DATA_CONTAINER_H #include "core/version.h" #include "core/io/resource.h" #include "core/variant/dictionary.h" class EntityDataContainer : public Resource { GDCLASS(EntityDataContainer, Resource); public: Dictionary to_dict(); void from_dict(const Dictionary &dict); Dictionary _to_dict(); void _from_dict(const Dictionary &dict); EntityDataContainer(); ~EntityDataContainer(); protected: static void _bind_methods(); }; #endif ================================================ FILE: entities/data/item_container_data.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "item_container_data.h" #include "../../defines.h" int ItemContainerData::get_num_container_datas() { return _container_datas.size(); } void ItemContainerData::set_num_container_datas(int value) { _container_datas.resize(value); } Ref ItemContainerData::get_container_data(int index) { ERR_FAIL_INDEX_V(index, _container_datas.size(), Ref()); return _container_datas[index]; } void ItemContainerData::set_container_data(int index, Ref container_data) { ERR_FAIL_INDEX(index, _container_datas.size()); _container_datas.set(index, container_data); } Vector ItemContainerData::get_container_datas() { VARIANT_ARRAY_GET(_container_datas); } void ItemContainerData::set_container_datas(const Vector &container_datas) { _container_datas.clear(); for (int i = 0; i < container_datas.size(); i++) { Ref container_data = Ref(container_datas[i]); _container_datas.push_back(container_data); } } ItemContainerData::ItemContainerData() { } ItemContainerData::~ItemContainerData() { _container_datas.clear(); } void ItemContainerData::_bind_methods() { ClassDB::bind_method(D_METHOD("get_num_container_datas"), &ItemContainerData::get_num_container_datas); ClassDB::bind_method(D_METHOD("set_num_container_datas", "value"), &ItemContainerData::set_num_container_datas); ClassDB::bind_method(D_METHOD("get_container_data", "index"), &ItemContainerData::get_container_data); ClassDB::bind_method(D_METHOD("set_container_data", "index", "container_data"), &ItemContainerData::set_container_data); ClassDB::bind_method(D_METHOD("get_container_datas"), &ItemContainerData::get_container_datas); ClassDB::bind_method(D_METHOD("set_container_datas", "container_datas"), &ItemContainerData::set_container_datas); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "container_datas", PROPERTY_HINT_NONE, "17/17:ItemContainerDataEntry", PROPERTY_USAGE_DEFAULT, "ItemContainerDataEntry"), "set_container_datas", "get_container_datas"); } ================================================ FILE: entities/data/item_container_data.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef ITEM_CONTAINER_DATA_H #define ITEM_CONTAINER_DATA_H #include "core/version.h" #include "core/io/resource.h" #include "item_container_data_entry.h" class ItemContainerData : public Resource { GDCLASS(ItemContainerData, Resource); public: int get_num_container_datas(); void set_num_container_datas(int value); Ref get_container_data(int index); void set_container_data(int index, Ref aura); Vector get_container_datas(); void set_container_datas(const Vector &ai_actions); ItemContainerData(); ~ItemContainerData(); protected: static void _bind_methods(); private: Vector > _container_datas; }; #endif ================================================ FILE: entities/data/item_container_data_entry.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "item_container_data_entry.h" #include "../../data/items/item_template.h" Ref ItemContainerDataEntry::get_item() { return _item; } void ItemContainerDataEntry::set_item(Ref item) { _item = item; } int ItemContainerDataEntry::get_item_count() const { return _item_count; } void ItemContainerDataEntry::set_item_count(int value) { _item_count = value; } ItemContainerDataEntry::ItemContainerDataEntry() { _item_count = 0; } ItemContainerDataEntry::~ItemContainerDataEntry() { } void ItemContainerDataEntry::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item"), &ItemContainerDataEntry::get_item); ClassDB::bind_method(D_METHOD("set_item", "item"), &ItemContainerDataEntry::set_item); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "ItemTemplate"), "set_item", "get_item"); ClassDB::bind_method(D_METHOD("get_item_count"), &ItemContainerDataEntry::get_item_count); ClassDB::bind_method(D_METHOD("set_item_count", "value"), &ItemContainerDataEntry::set_item_count); ADD_PROPERTY(PropertyInfo(Variant::INT, "item_count"), "set_item_count", "get_item_count"); } ================================================ FILE: entities/data/item_container_data_entry.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef CONTAINER_ITEM_DATA_H #define CONTAINER_ITEM_DATA_H #include "core/version.h" #include "core/io/resource.h" class ItemTemplate; class ItemContainerDataEntry : public Resource { GDCLASS(ItemContainerDataEntry, Resource); public: Ref get_item(); void set_item(Ref item); int get_item_count() const; void set_item_count(int value); ItemContainerDataEntry(); ~ItemContainerDataEntry(); protected: static void _bind_methods(); private: Ref _item; int _item_count; }; #endif ================================================ FILE: entities/data/vendor_item_data.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "vendor_item_data.h" #include "../../defines.h" int VendorItemData::get_num_vendor_datas() { return _vendor_datas.size(); } Ref VendorItemData::get_vendor_data(int index) { ERR_FAIL_INDEX_V(index, _vendor_datas.size(), Ref()); return _vendor_datas[index]; } void VendorItemData::set_vendor_data(int index, Ref vendor_data) { ERR_FAIL_INDEX(index, _vendor_datas.size()); _vendor_datas.set(index, vendor_data); } Vector VendorItemData::get_vendor_datas() { VARIANT_ARRAY_GET(_vendor_datas); } void VendorItemData::set_vendor_datas(const Vector &vendor_datas) { _vendor_datas.clear(); for (int i = 0; i < vendor_datas.size(); i++) { Ref vendor_data = Ref(vendor_datas[i]); _vendor_datas.push_back(vendor_data); } } VendorItemData::VendorItemData() { } VendorItemData::~VendorItemData() { _vendor_datas.clear(); } void VendorItemData::_bind_methods() { ClassDB::bind_method(D_METHOD("get_num_vendor_datas"), &VendorItemData::get_num_vendor_datas); ClassDB::bind_method(D_METHOD("get_vendor_data", "index"), &VendorItemData::get_vendor_data); ClassDB::bind_method(D_METHOD("set_vendor_data", "index", "vendor_data"), &VendorItemData::set_vendor_data); ClassDB::bind_method(D_METHOD("get_vendor_datas"), &VendorItemData::get_vendor_datas); ClassDB::bind_method(D_METHOD("set_vendor_datas", "vendor_datas"), &VendorItemData::set_vendor_datas); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "vendor_datas", PROPERTY_HINT_NONE, "17/17:VendorItemDataEntry", PROPERTY_USAGE_DEFAULT, "VendorItemDataEntry"), "set_vendor_datas", "get_vendor_datas"); } ================================================ FILE: entities/data/vendor_item_data.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef VENDOR_ITEM_DATA_H #define VENDOR_ITEM_DATA_H #include "core/version.h" #include "core/io/resource.h" #include "vendor_item_data_entry.h" class VendorItemData : public Resource { GDCLASS(VendorItemData, Resource); public: //Vendor data int get_num_vendor_datas(); Ref get_vendor_data(int index); void set_vendor_data(int index, Ref data); Vector get_vendor_datas(); void set_vendor_datas(const Vector &data); VendorItemData(); ~VendorItemData(); protected: static void _bind_methods(); private: Vector > _vendor_datas; }; #endif ================================================ FILE: entities/data/vendor_item_data_entry.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "vendor_item_data.h" #include "../../data/items/item_template.h" #include "../../data/spells/spell.h" Ref VendorItemDataEntry::get_item() { return _item; } void VendorItemDataEntry::set_item(const Ref &item) { _item = item; } Ref VendorItemDataEntry::get_spell() { return _spell; } void VendorItemDataEntry::set_spell(const Ref &spell) { _spell = spell; } Ref VendorItemDataEntry::get_cost_item() { return _cost_item; } void VendorItemDataEntry::set_cost_item(const Ref &item) { _cost_item = item; } int VendorItemDataEntry::get_price() const { return _price; } void VendorItemDataEntry::set_price(const int value) { _price = value; } int VendorItemDataEntry::get_count() const { return _count; } void VendorItemDataEntry::set_count(const int value) { _count = value; } int VendorItemDataEntry::get_spawn_time() const { return _spawn_time; } void VendorItemDataEntry::set_spawn_time(const int value) { _spawn_time = value; } VendorItemDataEntry::VendorItemDataEntry() { _price = 0; _count = 0; _spawn_time = 0; } VendorItemDataEntry::~VendorItemDataEntry() { _item.unref(); _spell.unref(); _cost_item.unref(); } void VendorItemDataEntry::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item"), &VendorItemDataEntry::get_item); ClassDB::bind_method(D_METHOD("set_item", "item"), &VendorItemDataEntry::set_item); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "ItemTemplate"), "set_item", "get_item"); ClassDB::bind_method(D_METHOD("get_spell"), &VendorItemDataEntry::get_spell); ClassDB::bind_method(D_METHOD("set_spell", "item"), &VendorItemDataEntry::set_spell); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "spell", PROPERTY_HINT_RESOURCE_TYPE, "Spell"), "set_spell", "get_spell"); ClassDB::bind_method(D_METHOD("get_cost_item"), &VendorItemDataEntry::get_cost_item); ClassDB::bind_method(D_METHOD("set_cost_item", "item"), &VendorItemDataEntry::set_cost_item); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "cost_item", PROPERTY_HINT_RESOURCE_TYPE, "ItemTemplate"), "set_cost_item", "get_cost_item"); ClassDB::bind_method(D_METHOD("get_price"), &VendorItemDataEntry::get_price); ClassDB::bind_method(D_METHOD("set_price", "value"), &VendorItemDataEntry::set_price); ADD_PROPERTY(PropertyInfo(Variant::INT, "price"), "set_price", "get_price"); ClassDB::bind_method(D_METHOD("get_count"), &VendorItemDataEntry::get_count); ClassDB::bind_method(D_METHOD("set_count", "value"), &VendorItemDataEntry::set_count); ADD_PROPERTY(PropertyInfo(Variant::INT, "count"), "set_count", "get_count"); ClassDB::bind_method(D_METHOD("get_spawn_time"), &VendorItemDataEntry::get_spawn_time); ClassDB::bind_method(D_METHOD("set_spawn_time", "value"), &VendorItemDataEntry::set_spawn_time); ADD_PROPERTY(PropertyInfo(Variant::INT, "spawn_time"), "set_spawn_time", "get_spawn_time"); } ================================================ FILE: entities/data/vendor_item_data_entry.h ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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. */ #ifndef VENDOR_ITEM_DATA_ENTRY_H #define VENDOR_ITEM_DATA_ENTRY_H #include "core/version.h" #include "core/io/resource.h" class ItemTemplate; class Spell; class VendorItemDataEntry : public Resource { GDCLASS(VendorItemDataEntry, Resource); public: Ref get_item(); void set_item(const Ref &item); Ref get_spell(); void set_spell(const Ref &spell); Ref get_cost_item(); void set_cost_item(const Ref &item); int get_price() const; void set_price(const int value); int get_count() const; void set_count(const int value); int get_spawn_time() const; void set_spawn_time(const int time); VendorItemDataEntry(); ~VendorItemDataEntry(); protected: static void _bind_methods(); private: Ref _item; Ref _spell; Ref _cost_item; int _price; int _count; int _spawn_time; }; #endif ================================================ FILE: entities/entity.cpp ================================================ /* Copyright (c) 2019-2022 Péter Magyar 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 "entity.h" #include "../database/ess_resource_db.h" #include "../singletons/ess.h" #include "../singletons/profile_manager.h" #include "../data/species/entity_species_data.h" #include "../data/spells/spell.h" #include "../entities/auras/aura_data.h" #include "../infos/spell_cast_info.h" #include "../inventory/bag.h" #include "../pipelines/spell_damage_info.h" #include "../pipelines/spell_heal_info.h" #include "../profiles/class_profile.h" #include "./data/character_spec.h" #include "./data/entity_data.h" #include "./data/vendor_item_data.h" #include "./data/vendor_item_data_entry.h" #include "./resources/entity_resource_health.h" #include "./resources/entity_resource_speed.h" #include "./skills/entity_skill.h" #include "scene/2d/node_2d.h" #include "core/object/script_language.h" #include "core/version.h" #include "../defines.h" #define PROPERTY_DEBUG false #if PROPERTY_DEBUG #define PROPERTY_USAGE_ENTITY_HIDDEN PROPERTY_USAGE_DEFAULT #else #define PROPERTY_USAGE_ENTITY_HIDDEN PROPERTY_USAGE_STORAGE #endif #define NOTIFICATION_IMPLS(func, signal, ...) \ if (_s_entity_controller == EntityEnums::ENITIY_CONTROLLER_AI && _s_ai.is_valid()) \ _s_ai->func(this, __VA_ARGS__); \ \ if (has_method("_" #func)) \ call("_" #func, __VA_ARGS__); \ \ for (int i = 0; i < _s_auras.size(); ++i) { \ Ref ad = _s_auras.get(i); \ ad->get_aura()->func(ad, __VA_ARGS__); \ } \ \ emit_signal(signal, this, __VA_ARGS__); #define NOTIFICATION_IMPLSS(func, signal) \ if (_s_entity_controller == EntityEnums::ENITIY_CONTROLLER_AI && _s_ai.is_valid()) \ _s_ai->func(this); \ \ if (has_method("_" #func)) \ call("_" #func); \ \ for (int i = 0; i < _s_auras.size(); ++i) { \ Ref ad = _s_auras.get(i); \ ad->get_aura()->func(ad); \ } \ \ emit_signal(signal, this); #define NOTIFICATION_IMPLC(func, signal, ...) \ if (has_method("_" #func)) \ call("_" #func, __VA_ARGS__); \ \ for (int i = 0; i < _c_auras.size(); ++i) { \ Ref ad = _c_auras.get(i); \ ad->get_aura()->func(ad, __VA_ARGS__); \ } \ \ emit_signal(signal, this, __VA_ARGS__); #define NOTIFICATION_IMPLCS(func, signal) \ if (has_method("_" #func)) \ call("_" #func); \ \ for (int i = 0; i < _c_auras.size(); ++i) { \ Ref ad = _c_auras.get(i); \ ad->get_aura()->func(ad); \ } \ \ emit_signal(signal, this); #define NOTIFICATION_RES_IMPLS(func, signal, ...) \ if (_s_entity_controller == EntityEnums::ENITIY_CONTROLLER_AI && _s_ai.is_valid()) \ _s_ai->func(__VA_ARGS__); \ \ if (has_method("_" #func)) \ call("_" #func, __VA_ARGS__); \ \ for (int i = 0; i < _s_auras.size(); ++i) { \ Ref ad = _s_auras.get(i); \ ad->get_aura()->func(ad, __VA_ARGS__); \ } \ \ emit_signal(signal, __VA_ARGS__); #define NOTIFICATION_RES_IMPLC(func, signal, ...) \ if (has_method("_" #func)) \ call("_" #func, __VA_ARGS__); \ \ for (int i = 0; i < _c_auras.size(); ++i) { \ Ref ad = _c_auras.get(i); \ ad->get_aura()->func(ad, __VA_ARGS__); \ } \ \ emit_signal(signal, __VA_ARGS__); #define NOTIFICATION_AURA_IMPLS(func, signal, what, ...) \ if (_s_entity_controller == EntityEnums::ENITIY_CONTROLLER_AI && _s_ai.is_valid()) \ _s_ai->func(what, __VA_ARGS__); \ \ if (has_method("_" #func)) \ call("_" #func, what, __VA_ARGS__); \ \ for (int i = 0; i < _s_auras.size(); ++i) { \ Ref ad = _s_auras.get(i); \ ad->get_aura()->func(what, ad, __VA_ARGS__); \ } \ \ emit_signal(signal, what, __VA_ARGS__); #define NOTIFICATION_AURA_DIFF_IMPLS(func, aura_func, signal, what, ...) \ if (_s_entity_controller == EntityEnums::ENITIY_CONTROLLER_AI && _s_ai.is_valid()) \ _s_ai->func(what, __VA_ARGS__); \ \ if (has_method("_" #func)) \ call("_" #func, what, __VA_ARGS__); \ \ for (int i = 0; i < _s_auras.size(); ++i) { \ Ref ad = _s_auras.get(i); \ ad->get_aura()->aura_func(what, ad, __VA_ARGS__); \ } \ \ emit_signal(signal, what, __VA_ARGS__); #define NOTIFICATION_AURA_IMPLC(func, signal, what, ...) \ if (has_method("_" #func)) \ call("_" #func, what, __VA_ARGS__); \ \ for (int i = 0; i < _c_auras.size(); ++i) { \ Ref ad = _c_auras.get(i); \ ad->get_aura()->func(what, ad, __VA_ARGS__); \ } \ \ emit_signal(signal, what, __VA_ARGS__); NodePath Entity::get_body_path() { return _body_path; } void Entity::set_body_path(NodePath value) { _body_path = value; set_body(get_node_or_null(_body_path)); if (INSTANCE_VALIDATE(_body)) _body->set_owner(this); } Node *Entity::get_body() { return _body; } Spatial *Entity::get_body_3d() { return _body_3d; } Node2D *Entity::get_body_2d() { return _body_2d; } void Entity::set_body(Node *body) { _body = body; _body_2d = Object::cast_to(body); _body_3d = Object::cast_to(body); } void Entity::instance_body(const Ref &data, const int model_index) { if (is_queued_for_deletion()) return; if (get_body() == NULL && data.is_valid() && data->get_entity_species_data().is_valid() && data->get_entity_species_data()->get_model_data_count() > model_index && data->get_entity_species_data()->get_model_data(model_index).is_valid() && data->get_entity_species_data()->get_model_data(model_index)->get_body().is_valid()) { Node *node = data->get_entity_species_data()->get_model_data(model_index)->get_body()->instantiate(); add_child(node); set_body(node); on_body_changed(); } } void Entity::on_body_changed() { if (has_method("_body_changed")) call("_body_changed"); emit_signal("body_changed", this); } NodePath Entity::get_character_skeleton_path() { return _character_skeleton_path; } void Entity::set_character_skeleton_path(NodePath value) { _character_skeleton_path = value; set_character_skeleton(get_node_or_null(_character_skeleton_path)); } Node *Entity::get_character_skeleton() { return _character_skeleton; } void Entity::set_character_skeleton(Node *skeleton) { _character_skeleton = skeleton; if (INSTANCE_VALIDATE(_character_skeleton) && _character_skeleton->has_method("add_model_visual")) { for (int i = 0; i < _c_equipment.size(); ++i) { Ref ii = _c_equipment[i]; if (ii.is_valid()) _character_skeleton->call("add_model_visual", ii->get_item_template()->get_model_visual()); } } } //GUID int Entity::gets_guid() { return _s_guid; } void Entity::sets_guid(int value) { _s_guid = value; VRPC(setc_guid, value); } int Entity::getc_guid() { return _c_guid; } void Entity::setc_guid(int value) { _c_guid = value; //set_name(String::num(_c_guid)); } //Transforms Transform3D Entity::get_transform_3d(bool only_stored) const { if (!only_stored && _body_3d) { ERR_FAIL_COND_V(!INSTANCE_VALIDATE(_body_3d), _transform); return _body_3d->get_transform(); } return _transform; } void Entity::set_transform_3d(const Transform3D &transform, bool only_stored) { if (!only_stored && _body_3d) { ERR_FAIL_COND(!INSTANCE_VALIDATE(_body_3d)); return _body_3d->set_transform(transform); } _transform = transform; } Transform2D Entity::get_transform_2d(bool only_stored) const { if (!only_stored && _body_2d) { ERR_FAIL_COND_V(!INSTANCE_VALIDATE(_body_2d), _transform_2d); return _body_2d->get_transform(); } return _transform_2d; } void Entity::set_transform_2d(const Transform2D &transform, bool only_stored) { if (!only_stored && _body_2d) { ERR_FAIL_COND(!INSTANCE_VALIDATE(_body_2d)); return _body_2d->set_transform(_transform_2d); } _transform_2d = transform; } //EntityPlayerType int Entity::gets_entity_player_type() { return _s_entity_player_type; } void Entity::sets_entity_player_type(int value) { _s_entity_player_type = value; VRPC(setc_entity_player_type, value); } int Entity::getc_entity_player_type() { return _c_entity_player_type; } void Entity::setc_entity_player_type(int value) { _c_entity_player_type = value; } //EntityType int Entity::gets_entity_type() { return _s_entity_type; } void Entity::sets_entity_type(int value) { _s_entity_type = value; VRPC(setc_entity_type, value); } int Entity::getc_entity_type() { return _c_entity_type; } void Entity::setc_entity_type(int value) { _c_entity_type = value; } //Relations EntityEnums::EntityRelationType Entity::gets_relation_to_bind(Node *to) { Entity *e = Object::cast_to(to); ERR_FAIL_COND_V(!INSTANCE_VALIDATE(e), EntityEnums::ENTITY_RELATION_TYPE_NEUTRAL); return gets_relation_to(e); } EntityEnums::EntityRelationType Entity::gets_relation_to(Entity *to) { ERR_FAIL_COND_V(!INSTANCE_VALIDATE(to), EntityEnums::ENTITY_RELATION_TYPE_NEUTRAL); return static_cast(static_cast(call("_gets_relation_to", to))); } EntityEnums::EntityRelationType Entity::_gets_relation_to(Node *to) { if (to == this) return EntityEnums::ENTITY_RELATION_TYPE_FRIENDLY; return EntityEnums::ENTITY_RELATION_TYPE_HOSTILE; } EntityEnums::EntityRelationType Entity::getc_relation_to_bind(Node *to) { Entity *e = Object::cast_to(to); ERR_FAIL_COND_V(!INSTANCE_VALIDATE(e), EntityEnums::ENTITY_RELATION_TYPE_NEUTRAL); return getc_relation_to(e); } EntityEnums::EntityRelationType Entity::getc_relation_to(Entity *to) { ERR_FAIL_COND_V(!INSTANCE_VALIDATE(to), EntityEnums::ENTITY_RELATION_TYPE_NEUTRAL); return static_cast(static_cast(call("_getc_relation_to", to))); } EntityEnums::EntityRelationType Entity::_getc_relation_to(Node *to) { if (to == this) return EntityEnums::ENTITY_RELATION_TYPE_FRIENDLY; return EntityEnums::ENTITY_RELATION_TYPE_HOSTILE; } //EntityInteractionType EntityEnums::EntityInteractionType Entity::gets_entity_interaction_type() { return _s_interaction_type; } void Entity::sets_entity_interaction_type(EntityEnums::EntityInteractionType value) { _s_interaction_type = value; VRPC(setc_entity_interaction_type, value); } EntityEnums::EntityInteractionType Entity::getc_entity_interaction_type() { return _c_interaction_type; } void Entity::setc_entity_interaction_type(EntityEnums::EntityInteractionType value) { _c_interaction_type = value; } int Entity::gets_immunity_flags() { return _s_immunity_flags; } void Entity::sets_immunity_flags(int value) { _s_immunity_flags = value; } int Entity::gets_entity_flags() { return _s_entity_flags; } void Entity::sets_entity_flags(int value) { _s_entity_flags = value; VRPC(setc_entity_flags, value); } int Entity::getc_entity_flags() { return _c_entity_flags; } void Entity::setc_entity_flags(int value) { _c_entity_flags = value; } String Entity::gets_entity_name() { return _s_entity_name; } void Entity::sets_entity_name(String value) { _s_entity_name = value; emit_signal("sname_changed", this); VRPC(setc_entity_name, value); } String Entity::getc_entity_name() { return _c_entity_name; } void Entity::setc_entity_name(String value) { _c_entity_name = value; emit_signal("cname_changed", this); } int Entity::gets_model_index() { return _s_model_index; } void Entity::sets_model_index(int value) { _s_model_index = value; VRPC(setc_model_index, value); } int Entity::getc_model_index() { return _c_model_index; } void Entity::setc_model_index(int value) { _c_model_index = value; if (INSTANCE_VALIDATE(_character_skeleton)) { if (_character_skeleton->has_method("set_model_index")) _character_skeleton->call("set_model_index", _c_model_index); } } int Entity::gets_level() { return _s_level; } void Entity::sets_level(int value) { _s_level = value; emit_signal("son_level_changed", this, value); VRPC(setc_level, value); } int Entity::getc_level() { return _c_level; } void Entity::setc_level(int value) { _c_level = value; emit_signal("con_level_changed", this, value); } int Entity::gets_xp() { return _s_xp; } void Entity::sets_xp(int value) { _s_xp = value; ORPC(setc_xp, value); } int Entity::getc_xp() { return _c_xp; } void Entity::setc_xp(int value) { _c_xp = value; } int Entity::gets_money() { return _s_money; } void Entity::sets_money(int value) { _s_money = value; ORPC(setc_money, value); } int Entity::getc_money() { return _c_money; } void Entity::setc_money(int value) { _c_money = value; } int Entity::gets_entity_data_id() { return _s_class_id; } void Entity::sets_entity_data_id(int value) { _s_class_id = value; } int Entity::getc_entity_data_id() { return _c_class_id; } void Entity::setc_entity_data_id(int value) { _c_class_id = value; if (_c_class_id == 0) { setc_entity_data(Ref()); return; } if (ESS::get_singleton() != NULL) { setc_entity_data(ESS::get_singleton()->get_resource_db()->get_entity_data(_c_class_id)); } } StringName Entity::gets_entity_data_path() { return _s_entity_data_path; } void Entity::sets_entity_data_path(const StringName &value) { _s_entity_data_path = value; } Ref Entity::gets_entity_data() { return _s_entity_data; } void Entity::sets_entity_data(Ref value) { if (is_queued_for_deletion()) { return; } _s_class_id = 0; if (value.is_valid()) { _s_class_id = value->get_id(); } _s_entity_data = value; //setup(); instance_body(value, _s_model_index); emit_signal("sentity_data_changed", value); VRPC(setc_entity_data_id, _s_class_id); } Ref Entity::getc_entity_data() { return _c_entity_data; } void Entity::setc_entity_data(Ref value) { _c_entity_data = value; instance_body(value, _c_model_index); emit_signal("centity_data_changed", value); } EntityEnums::AIStates Entity::gets_ai_state() const { return _sai_state; } void Entity::sets_ai_state(EntityEnums::AIStates state) { _sai_state = state; } EntityEnums::AIStates Entity::gets_ai_state_stored() const { return _sai_state_stored; } void Entity::sets_ai_state_stored(EntityEnums::AIStates state) { _sai_state_stored = state; } int Entity::gets_seed() { return _s_seed; } void Entity::sets_seed(int value) { _s_seed = value; ORPC(setc_seed, value); } int Entity::getc_seed() { return _c_seed; } void Entity::setc_seed(int value) { _c_seed = value; } void Entity::_initialize() { _s_resources.resize(EntityEnums::ENTITY_RESOURCE_INDEX_RESOURCES_BEGIN); _c_resources.resize(EntityEnums::ENTITY_RESOURCE_INDEX_RESOURCES_BEGIN); _s_resources.set(EntityEnums::ENTITY_RESOURCE_INDEX_HEALTH, Ref(memnew(EntityResourceHealth))); _s_resources.set(EntityEnums::ENTITY_RESOURCE_INDEX_SPEED, Ref(memnew(EntityResourceSpeed))); _c_resources.set(EntityEnums::ENTITY_RESOURCE_INDEX_HEALTH, Ref(memnew(EntityResourceHealth))); _c_resources.set(EntityEnums::ENTITY_RESOURCE_INDEX_SPEED, Ref(memnew(EntityResourceSpeed))); for (int i = 0; i < EntityEnums::ENTITY_RESOURCE_INDEX_RESOURCES_BEGIN; ++i) { _s_resources.get(i)->set_owner(this); _c_resources.get(i)->set_owner(this); } } void Entity::setup(Ref info) { ERR_FAIL_COND(!info.is_valid()); sets_guid(info->get_guid()); sets_entity_player_type(info->get_entity_player_type()); if (info->get_network_owner() != 0) { set_multiplayer_authority(info->get_network_owner()); } sets_original_entity_controller(info->get_entity_controller()); sets_entity_controller(info->get_entity_controller()); _s_level = info->get_level(); _s_xp = info->get_xp(); if (info->get_entity_name() != "") { sets_entity_name(info->get_entity_name()); } if (!info->get_serialized_data().is_empty()) { from_dict(info->get_serialized_data()); } else { sets_entity_data(info->get_entity_data()); } if (has_method("_setup")) { #if GODOT4 call("_setup"); #else call_multilevel("_setup"); #endif } } void Entity::_setup() { if (!_s_entity_data.is_valid()) return; if (_deserialized) { Ref cc = gets_entity_data()->get_entity_class_data(); ERR_FAIL_COND(!cc.is_valid()); //Ref stat_data = _s_entity_data->get_stat_data(); sets_ai(_s_entity_data->get_ai_instance()); for (int i = 0; i < _s_auras.size(); ++i) { Ref ad = _s_auras.get(i); if (!ad->get_aura()->aura_get_hide()) VRPCOBJ(aura_addc_rpc, JSON::stringify(ad->to_dict()), aura_addc, ad); } if (gets_entity_player_type() == EntityEnums::ENTITY_PLAYER_TYPE_PLAYER || gets_entity_player_type() == EntityEnums::ENTITY_PLAYER_TYPE_DISPLAY) { /* if (ESS::get_singleton()->get_use_global_class_level()) { Ref cp = ProfileManager::get_singleton()->getc_player_profile()->get_class_profile(gets_entity_data()->get_path()); if (cp.is_valid()) { int leveldiff = cp->get_level() - _s_level; sets_class_level(cp->get_level()); if (leveldiff > 0) { levelup_sclass(leveldiff); } sets_class_xp(cp->get_xp()); } } */ setup_actionbars(); } if (gets_entity_player_type() == EntityEnums::ENTITY_PLAYER_TYPE_AI) { sets_entity_name(_s_entity_data->get_name()); } return; } ERR_FAIL_COND(!gets_entity_data().is_valid()); Ref cc = gets_entity_data()->get_entity_class_data(); ERR_FAIL_COND(!cc.is_valid()); Ref stat_data = cc->get_stat_data(); ERR_FAIL_COND(!stat_data.is_valid()); for (int i = 0; i < ESS::get_singleton()->stat_get_count(); ++i) { stat_set_base(i, stat_data->get_base(i)); } for (int i = 0; i < ESS::get_singleton()->stat_get_count(); ++i) { stat_setc_current(i, stat_gets_current(i)); stat_set_dirty(i, false); } for (int i = 0; i < cc->get_num_auras(); ++i) { Ref a = cc->get_aura(i); if (a.is_valid()) { a->aura_sapply_simple(this, this, 1.0); } } _s_entity_data->setup_resources(this); sets_entity_data_id(_s_entity_data->get_id()); Ref spd = _s_entity_data->get_entity_species_data(); if (spd.is_valid()) { sets_entity_type(spd->get_type()); } else { sets_entity_type(0); } sets_entity_interaction_type(_s_entity_data->get_entity_interaction_type()); sets_immunity_flags(_s_entity_data->get_immunity_flags()); sets_entity_flags(_s_entity_data->get_entity_flags()); //if (_s_entity_controller == EntityEnums::ENITIY_CONTROLLER_NONE) { // sets_original_entity_controller(_s_entity_data->get_entity_controller()); // sets_entity_controller(_s_entity_data->get_entity_controller()); //} //sets_entity_name(_s_entity_data->get_entity_name()); sets_money(_s_entity_data->get_money()); Ref cd = _s_entity_data->get_entity_class_data(); if (cd.is_valid()) { for (int i = 0; i < cd->get_num_start_spells(); ++i) { spell_adds(cd->get_start_spell(i)); } } for (int i = 0; i < cc->get_num_craft_recipes(); ++i) { craft_adds_recipe(cc->get_craft_recipe(i)); } if (_s_entity_data->get_equipment_data().is_valid()) { Ref eqd = _s_entity_data->get_equipment_data(); for (int i = 0; i < ESS::get_singleton()->equip_slot_get_count(); ++i) { Ref ii = eqd->get_item(i); if (ii.is_valid()) _s_equipment.write[i] = ii; } } sets_ai(_s_entity_data->get_ai_instance()); if (!Engine::get_singleton()->is_editor_hint()) set_process(_s_entity_data.is_valid()); if (gets_entity_player_type() == EntityEnums::ENTITY_PLAYER_TYPE_PLAYER || gets_entity_player_type() == EntityEnums::ENTITY_PLAYER_TYPE_DISPLAY) { setup_actionbars(); } if (gets_entity_player_type() == EntityEnums::ENTITY_PLAYER_TYPE_AI) { sets_entity_name(_s_entity_data->get_name()); } int chl = _s_level; int chxp = _s_xp; _s_level = 1; levelups(chl - 1); sets_xp(chxp); if (ESS::get_singleton()->get_allow_class_spell_learning()) { Ref class_profile = ProfileManager::get_singleton()->getc_player_profile()->get_class_profile(_s_entity_data->get_path()); 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) { spell_adds_id(ESS::get_singleton()->get_resource_db()->spell_path_to_id(spells.get(i))); } } } if (ESS::get_singleton()->get_allow_class_recipe_learning()) { Ref class_profile = ProfileManager::get_singleton()->getc_player_profile()->get_class_profile(_s_entity_data->get_path()); 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) { craft_adds_recipe_id(ESS::get_singleton()->get_resource_db()->craft_recipe_path_to_id(recipes.get(i))); } } } } void Entity::setup_actionbars() { if (!gets_entity_data().is_valid()) return; if (is_deserialized()) { return; } get_action_bar_profile(); /* ProfileManager *pm = ProfileManager::get_singleton(); if (pm != NULL) { Ref cp = get_class_profile(); if (cp.is_valid()) { set_actionbar_locked(cp->get_actionbar_locked()); _action_bar_profile = cp->get_default_action_bar_profile(); get_action_bar_profile()->clear_action_bars(); Ref abp = cp->get_action_bar_profile(); get_action_bar_profile()->from_actionbar_profile(abp); } }*/ if (!gets_bag().is_valid()) { Ref bag; bag.instantiate(); bag->set_size(gets_entity_data()->get_bag_size()); sets_bag(bag); } } // AI bool Entity::gets_is_pet() { return _s_pet_owner; } bool Entity::getc_is_pet() { return _c_pet_owner; } Entity *Entity::pet_gets_owner() { return _s_pet_owner; } void Entity::pet_sets_owner(Entity *entity) { _s_pet_owner = entity; } void Entity::pet_sets_owner_bind(Node *entity) { if (!entity) { return; } Entity *e = cast_to(entity); if (!e) { return; } return pet_sets_owner(e); } int Entity::pet_gets_formation_index() { return _s_pet_formation_index; } void Entity::pet_sets_formation_index(int value) { _s_pet_formation_index = value; } EntityEnums::AIStates Entity::pet_gets_ai_state() { return _s_pet_ai_state; } void Entity::pet_sets_ai_state(EntityEnums::AIStates value) { _s_pet_ai_state = value; } EntityEnums::EntityController Entity::gets_original_entity_controller() { return _s_entity_controller; } void Entity::sets_original_entity_controller(EntityEnums::EntityController value) { _s_entity_controller = value; } EntityEnums::EntityController Entity::gets_entity_controller() { return _s_entity_controller; } void Entity::sets_entity_controller(EntityEnums::EntityController value) { _s_entity_controller = value; ORPC(setc_entity_controller, value); } EntityEnums::EntityController Entity::getc_entity_controller() { return _s_entity_controller; } void Entity::setc_entity_controller(EntityEnums::EntityController value) { if (_c_entity_controller == value) { return; } _c_entity_controller = value; emit_signal("onc_entity_controller_changed"); } bool Entity::getc_is_controlled() { Ref _multiplayer_api = get_multiplayer(); if (_multiplayer_api.is_valid()) { return (_c_entity_controller == EntityEnums::ENITIY_CONTROLLER_PLAYER) && (get_multiplayer_authority() == _multiplayer_api->get_unique_id()); } else { return _c_entity_controller == EntityEnums::ENITIY_CONTROLLER_PLAYER; } } Ref Entity::gets_ai() { return _s_ai; } void Entity::sets_ai(Ref value) { if (_s_ai.is_valid()) { _s_ai->set_owner(NULL); _s_ai.unref(); } _s_ai = value; _s_ai->set_owner(this); } //// Pets //// void Entity::pet_adds(Entity *entity) { ERR_FAIL_COND(!INSTANCE_VALIDATE(entity)); //the owner always want to see his pet, and you pet will always want to see the owner sees_adds(entity); entity->sees_adds(this); entity->pet_sets_owner(this); _s_pets.push_back(entity); entity->sets_ai_state_stored(entity->gets_ai_state()); entity->sets_ai_state(_s_pet_ai_state); entity->sets_entity_controller(EntityEnums::ENITIY_CONTROLLER_AI); entity->pet_sets_formation_index(_s_pets.size()); //full callback stack spet_added } void Entity::pet_adds_bind(Node *entity) { Entity *e = Object::cast_to(entity); ERR_FAIL_COND(!e); pet_adds(e); } Entity *Entity::pet_gets(int index) { ERR_FAIL_INDEX_V(index, _s_pets.size(), NULL); return _s_pets.get(index); } void Entity::pet_removes_index(int index) { ERR_FAIL_INDEX(index, _s_pets.size()); Entity *entity = _s_pets.get(index); _s_pets.remove_at(index); sees_removes(entity); for (int i = 0; i < _s_pets.size(); ++i) { Entity *pet = _s_pets.get(index); ERR_CONTINUE(!INSTANCE_VALIDATE(pet)); _s_pets.get(i)->pet_sets_formation_index(i); } ERR_FAIL_COND(!INSTANCE_VALIDATE(entity)); entity->pet_sets_owner(NULL); entity->sets_ai_state(entity->gets_ai_state_stored()); entity->sets_entity_controller(entity->gets_original_entity_controller()); //full callback stack spet_added } void Entity::pet_removes(Entity *entity) { for (int i = 0; i < _s_pets.size(); ++i) { if (_s_pets.get(i) == entity) { pet_removes_index(i); return; } } } void Entity::pet_removes_bind(Node *entity) { Entity *e = Object::cast_to(entity); ERR_FAIL_COND(!e); pet_removes(e); } int Entity::pet_gets_count() { return _s_pets.size(); } void Entity::pet_addc_path(NodePath path) { Node *n = get_node_or_null(path); Entity *entity = Object::cast_to(n); ERR_FAIL_COND(!INSTANCE_VALIDATE(entity)); pet_addc(entity); } void Entity::pet_addc(Entity *entity) { ERR_FAIL_COND(!INSTANCE_VALIDATE(entity)); _c_pets.push_back(entity); //full callback stack spet_added } void Entity::pet_addc_bind(Node *entity) { Entity *e = Object::cast_to(entity); ERR_FAIL_COND(!e); pet_addc(e); } Entity *Entity::pet_getc(int index) { ERR_FAIL_INDEX_V(index, _c_pets.size(), NULL); return _c_pets.get(index); } void Entity::pet_removec_index(int index) { ERR_FAIL_INDEX(index, _c_pets.size()); //Entity *entity = _c_pets.get(index); _c_pets.remove_at(index); //#if VERSION_MAJOR < 4 //ERR_FAIL_COND(!ObjectDB::instance_validate(entity)); //#else //ERR_FAIL_COND(entity == NULL); //#endif //full callback stack spet_added } void Entity::pet_removec(Entity *entity) { for (int i = 0; i < _c_pets.size(); ++i) { if (_c_pets.get(i) == entity) { pet_removec_index(i); return; } } } void Entity::pet_removec_bind(Node *entity) { Entity *e = Object::cast_to(entity); ERR_FAIL_COND(!e); pet_removec(e); } int Entity::pet_getc_count() { return _s_pets.size(); } //// Profiles //// Ref Entity::get_class_profile() { return ProfileManager::get_singleton()->getc_player_profile()->get_class_profile(_s_entity_data->get_path()); } //// Serialization //// bool Entity::is_deserialized() { return _deserialized; } Dictionary Entity::to_dict() { return call("_to_dict"); } void Entity::from_dict(const Dictionary &dict) { _deserialized = true; call("_from_dict", dict); emit_signal("deserialized", this); } Dictionary Entity::_to_dict() { Dictionary dict; //// Transforms //// //Not needed (at least atm) //// PlayerData //// dict["guid"] = _s_guid; //dict["entity_data_id"] = _s_class_id; if (_s_entity_data.is_valid()) dict["entity_data_path"] = _s_entity_data->get_path(); else dict["entity_data_path"] = _s_entity_data_path; //int _s_entity_player_type; dict["type"] = _s_type; dict["model_index"] = _s_model_index; dict["level"] = _s_level; dict["xp"] = gets_xp(); dict["money"] = _s_money; //dict["send_flag"] = _s_send_flag; dict["entity_name"] = _s_entity_name; dict["interaction_type"] = static_cast(_s_interaction_type); //int _s_is_dead; dict["seed"] = _s_seed; dict["entity_type"] = _s_entity_type; dict["immunity_flags"] = _s_immunity_flags; dict["entity_flags"] = _s_entity_flags; //dict["entity_controller"] = _s_entity_controller; //dict["entity_controller"] = _s_original_entity_controller; //// Stats //// Dictionary sd; for (int i = 0; i < ESS::get_singleton()->stat_get_count(); ++i) { Dictionary sdict; sdict["base"] = stat_get_base(i); sdict["base_calculated"] = stat_get_base_calculated(i); sdict["bonus"] = stat_get_bonus(i); sdict["percent"] = stat_get_percent(i); sdict["current"] = stat_gets_current(i); sd[i] = sdict; } dict["stats"] = sd; //// Equipment //// Dictionary equipment; for (int i = 0; i < ESS::get_singleton()->equip_slot_get_count(); ++i) { Ref ii = _s_equipment[i]; if (ii.is_valid()) equipment[i] = ii->to_dict(); } dict["equipment"] = equipment; //// Resources //// Dictionary rd; for (int i = 0; i < _s_resources.size(); ++i) { Ref r = _s_resources.get(i); ERR_CONTINUE(!r.is_valid()); rd[String::num(i)] = r->to_dict(); } dict["resources"] = rd; //// GCD //// dict["gcd"] = _s_gcd; //// States //// Dictionary stated; for (int i = 0; i < EntityEnums::ENTITY_STATE_TYPE_INDEX_MAX; ++i) { stated[i] = _s_states[i]; } dict["states"] = stated; dict["state"] = _s_state; //// SpellCastData //// //Not needed //Ref _s_spell_cast_info; //Ref _c_spell_cast_info; //// AuraComponent //// Dictionary auras; for (int i = 0; i < _s_auras.size(); ++i) { auras[i] = _s_auras.get(i)->to_dict(); } dict["auras"] = auras; //// Cooldowns //// Dictionary cds; for (int i = 0; i < _s_cooldowns.size(); ++i) { Dictionary cdict; cdict["path"] = ESS::get_singleton()->get_resource_db()->spell_id_to_path(_s_cooldowns[i].id); cdict["remaining"] = _s_cooldowns[i].cooldown; cds[i] = cdict; } dict["cooldowns"] = cds; Dictionary ccds; for (int i = 0; i < _s_category_cooldowns.size(); ++i) { Dictionary ccdict; ccdict["path"] = ESS::get_singleton()->get_resource_db()->spell_id_to_path(_s_category_cooldowns[i].id); ccdict["remaining"] = _s_category_cooldowns[i].cooldown; ccds[i] = ccdict; } dict["category_cooldowns"] = ccds; dict["active_category_cooldowns"] = _s_active_category_cooldowns; //// Talents //// dict["free_class_talent_points"] = _s_free_class_talent_points; dict["class_talents"] = _s_class_talents; dict["free_character_talent_points"] = _s_free_character_talent_points; dict["character_talents"] = _s_character_talents; //// Data //// Array entity_datas; for (int i = 0; i < _s_data.size(); ++i) { entity_datas.append(_s_data.get(i)->to_dict()); } dict["entity_datas"] = entity_datas; //// Crafting //// Dictionary known_recipes; for (int i = 0; i < _s_craft_recipes.size(); ++i) { known_recipes[i] = _s_craft_recipes.get(i)->get_path(); } dict["known_recipes"] = known_recipes; //// Known Spells //// if (ESS::get_singleton()->get_use_spell_points()) dict["free_spell_points"] = _s_free_spell_points; Dictionary known_spells; for (int i = 0; i < _s_spells.size(); ++i) { known_spells[i] = _s_spells.get(i)->get_path(); } dict["known_spells"] = known_spells; //// Skills //// Dictionary skills; for (int i = 0; i < _s_skills.size(); ++i) { skills[i] = _s_skills.get(i)->to_dict(); } dict["skills"] = skills; //// Bags //// if (_s_bag.is_valid()) dict["bag"] = _s_bag->to_dict(); //// Actionbars //// dict["actionbar_locked"] = _actionbar_locked; if (_action_bar_profile.is_valid()) dict["actionbar_profile"] = _action_bar_profile->to_dict(); // AI //not needed //Pets //Not yet properly implemented // Callbacks //Probably not needed //Vector > _physics_process_scis; return dict; } void Entity::_from_dict(const Dictionary &dict) { ERR_FAIL_COND(dict.is_empty()); //// Transforms //// //Not needed for now //// PlayerData //// sets_guid(dict.get("guid", 0)); sets_entity_type(dict.get("type", 0)); //entity_data_path at end sets_model_index(static_cast(static_cast(dict.get("model_index", 0)))); /* if (ESS::get_singleton()->get_use_global_class_level()) { _s_level = (dict.get("class_level", 0)); _s_xp = (dict.get("class_xp", 0)); } else { sets_class_level(dict.get("class_level", 0)); sets_xp(dict.get("xp", 0)); } */ sets_level(dict.get("level", 0)); sets_xp(dict.get("xp", 0)); sets_money(dict.get("money", 0)); sets_entity_name(dict.get("entity_name", "")); sets_entity_interaction_type(static_cast(static_cast(dict.get("interaction_type", 0)))); //int _s_is_dead; sets_seed(dict.get("seed", _s_seed)); //EntityPlayerType not needed sets_immunity_flags(dict.get("immunity_flags", 0)); sets_entity_flags(dict.get("entity_flags", 0)); //EntityEnums::EntityController contr = static_cast(static_cast(dict.get("entity_controller", 0))); //sets_original_entity_controller(contr); //sets_entity_controller(contr); //// Stats //// Dictionary stats = dict.get("stats", Dictionary()); for (int i = 0; i < ESS::get_singleton()->stat_get_count(); ++i) { Dictionary sd = stats.get(String::num(i), Dictionary()); stat_set_base(i, sd.get("base", 0)); stat_set_base_calculated(i, sd.get("base_calculated", 0)); stat_set_bonus(i, sd.get("bonus", 0)); stat_set_percent(i, sd.get("percent", 1)); float curr = sd.get("current", 0); stat_sets_current(i, curr); stat_setc_current(i, curr); stat_set_dirty(i, true); } //// Equipment //// Dictionary equipment = dict.get("equipment", Dictionary()); for (int i = 0; i < ESS::get_singleton()->equip_slot_get_count(); ++i) { if (equipment.has(String::num(i))) { Ref ii = _s_equipment[i]; if (!ii.is_valid()) { ii.instantiate(); } ii->from_dict(equipment[String::num(i)]); _s_equipment.write[i] = ii; _c_equipment.write[i] = ii; } } //// Resources //// _s_resources.resize(EntityEnums::ENTITY_RESOURCE_INDEX_RESOURCES_BEGIN); _c_resources.resize(EntityEnums::ENTITY_RESOURCE_INDEX_RESOURCES_BEGIN); Dictionary rd = dict.get("resources", Dictionary()); Dictionary hpdict = rd.get(String::num(EntityEnums::ENTITY_RESOURCE_INDEX_HEALTH), Dictionary()); _s_resources.get(EntityEnums::ENTITY_RESOURCE_INDEX_HEALTH)->from_dict(hpdict); _c_resources.get(EntityEnums::ENTITY_RESOURCE_INDEX_HEALTH)->from_dict(hpdict); Dictionary speeddict = rd.get(String::num(EntityEnums::ENTITY_RESOURCE_INDEX_SPEED), Dictionary()); _s_resources.get(EntityEnums::ENTITY_RESOURCE_INDEX_SPEED)->from_dict(speeddict); _c_resources.get(EntityEnums::ENTITY_RESOURCE_INDEX_SPEED)->from_dict(speeddict); for (int i = EntityEnums::ENTITY_RESOURCE_INDEX_RESOURCES_BEGIN; i < rd.size(); ++i) { Dictionary ird = rd.get(String::num(i), Dictionary()); StringName data_path = ird.get("data_path", ""); Ref resd = ESS::get_singleton()->get_resource_db()->get_entity_resource_path(data_path); ERR_CONTINUE(!resd.is_valid()); Ref res = resd->duplicate(); ERR_CONTINUE(!res.is_valid()); res->from_dict(ird); resource_adds(res); } //// GCD //// _s_gcd = dict.get("gcd", 0); _c_gcd = _s_gcd; //// States //// Dictionary statesd = dict.get("states", Dictionary()); for (int i = 0; i < EntityEnums::ENTITY_STATE_TYPE_INDEX_MAX; ++i) { _s_states[i] = statesd.get(String::num(i), 0); } _s_state = dict.get("state", Dictionary()); _c_state = _s_state; //// SpellCastData //// //Not needed //// Auras //// _s_auras.clear(); _c_auras.clear(); Dictionary auras = dict.get("auras", Dictionary()); for (int i = 0; i < auras.size(); ++i) { Ref r; r.instantiate(); r->from_dict(auras.get(String::num(i), Dictionary())); r->set_owner(this); r->resolve_references(this); _s_auras.push_back(r); //_c_auras.push_back(r); } //// Cooldowns //// _s_cooldowns.clear(); _c_cooldowns.clear(); Dictionary cds = dict.get("cooldowns", Dictionary()); for (int i = 0; i < cds.size(); ++i) { Dictionary cddict = cds.get(String::num(i), Dictionary()); Cooldown cd; cd.path = dict.get("path", ""); cd.id = ESS::get_singleton()->get_resource_db()->spell_path_to_id(cd.path); cd.cooldown = dict.get("remaining", 0); _s_cooldowns.push_back(cd); _c_cooldowns.push_back(cd); } Dictionary ccds = dict.get("category_cooldowns", Dictionary()); for (int i = 0; i < ccds.size(); ++i) { Dictionary ccdict = ccds.get(String::num(i), Dictionary()); Cooldown ccd; ccd.path = dict.get("path", ""); ccd.id = ESS::get_singleton()->get_resource_db()->spell_path_to_id(ccd.path); ccd.cooldown = dict.get("remaining", 0); _s_category_cooldowns.push_back(ccd); _c_category_cooldowns.push_back(ccd); } _s_active_category_cooldowns = dict.get("active_category_cooldowns", 0); _c_active_category_cooldowns = _s_active_category_cooldowns; //// Class Talents //// _s_free_class_talent_points = dict.get("free_class_talent_points", 0); _c_free_class_talent_points = _s_free_class_talent_points; Vector class_talents = dict.get("class_talents", Vector()); for (int i = 0; i < class_talents.size(); ++i) { class_talent_adds(class_talents[i]); } //// Character Talents //// _s_free_character_talent_points = dict.get("free_character_talent_points", 0); _c_free_character_talent_points = _s_free_character_talent_points; Vector character_talents = dict.get("character_talents", Vector()); for (int i = 0; i < character_talents.size(); ++i) { character_talent_adds(character_talents[i]); } //// Data //// Array entity_datas = dict.get("entity_datas", Array()); for (int i = 0; i < entity_datas.size(); ++i) { Dictionary entry = entity_datas.get(i); String class_name = dict.get("class_name", EntityDataContainer::get_class_static()); if (ClassDB::can_instantiate(class_name) && ClassDB::is_parent_class(class_name, EntityDataContainer::get_class_static())) { Ref data = Ref(ClassDB::instantiate(class_name)); if (data.is_valid()) { data->from_dict(entry); _s_data.push_back(data); _c_data.push_back(data); } } } //// Crafting //// _s_craft_recipes.clear(); _c_craft_recipes.clear(); Dictionary known_recipes = dict.get("known_recipes", Dictionary()); for (int i = 0; i < known_recipes.size(); ++i) { StringName crn = known_recipes.get(String::num(i), ""); if (ESS::get_singleton() != NULL) { Ref cr = ESS::get_singleton()->get_resource_db()->get_craft_recipe_path(crn); if (cr.is_valid()) { craft_adds_recipe(cr); } } } //// Known Spells //// if (ESS::get_singleton()->get_use_spell_points()) sets_free_spell_points(dict.get("free_spell_points", 0)); Dictionary known_spells = dict.get("known_spells", Dictionary()); for (int i = 0; i < known_spells.size(); ++i) { StringName spell_path = known_spells.get(String::num(i), ""); if (ESS::get_singleton() != NULL) { Ref sp = ESS::get_singleton()->get_resource_db()->get_spell_path(spell_path); if (sp.is_valid()) { _s_spells.push_back(sp); _c_spells.push_back(sp); } } } //// Skills //// Dictionary skills = dict.get("skills", Dictionary()); for (int i = 0; i < skills.size(); ++i) { Ref r; r.instantiate(); r->from_dict(skills.get(String::num(i), Dictionary())); _s_skills.push_back(r); _c_skills.push_back(r); } //// Bags //// Dictionary bagd = dict.get("bag", Dictionary()); if (!bagd.is_empty()) { if (!_s_bag.is_valid()) { Ref bag; bag.instantiate(); bag->from_dict(bagd); sets_bag(bag); } else { _s_bag->from_dict(bagd); } } //// Actionbars //// _actionbar_locked = dict.get("actionbar_locked", false); if (dict.has("actionbar_profile")) { if (!_action_bar_profile.is_valid()) _action_bar_profile.instantiate(); _action_bar_profile->from_dict(dict.get("actionbar_profile", Dictionary())); } StringName edp = dict.get("entity_data_path", ""); if (ESS::get_singleton() != NULL) { sets_entity_data(ESS::get_singleton()->get_resource_db()->get_entity_data_path(edp)); } sets_entity_data_path(edp); // AI //Not needed right now //Pets //NYI // Networking //Not Needed // Callbacks //Not Needed } ////// Stat System ////// bool Entity::gets_is_dead() { return _s_is_dead; } bool Entity::getc_is_dead() { return _c_is_dead; } bool Entity::gcd_hasc() const { return _c_gcd >= 0.000000001; } bool Entity::gcd_hass() const { return _s_gcd >= 0.000000001; } float Entity::gcd_getc() const { return _c_gcd; } void Entity::gcd_setc(const float value) { _c_gcd = value; } float Entity::gcd_gets() const { return _s_gcd; } void Entity::gcd_sets(const float value) { _s_gcd = value; } void Entity::gcd_starts(float value) { _s_gcd = value; notification_sgcd_started(); ORPC(gcd_startc, value); } void Entity::gcd_startc(float value) { _c_gcd = value; notification_cgcd_started(); } //// States //// int Entity::gets_state() { return _s_state; } void Entity::sets_state(int state) { _s_state = state; emit_signal("sstate_changed", state); VRPC(setc_state, state); } int Entity::getc_state() { return _c_state; } void Entity::setc_state(int state) { _c_state = state; emit_signal("cstate_changed", state); } void Entity::adds_state_ref(int state_index) { ERR_FAIL_INDEX(state_index, EntityEnums::ENTITY_STATE_TYPE_INDEX_MAX); if (_s_states[state_index]++ == 0) { sets_state(gets_state() | EntityEnums::get_state_flag_for_index(state_index)); } } void Entity::removes_state_ref(int state_index) { ERR_FAIL_INDEX(state_index, EntityEnums::ENTITY_STATE_TYPE_INDEX_MAX); if (--_s_states[state_index] == 0) { sets_state(gets_state() ^ EntityEnums::get_state_flag_for_index(state_index)); } } PoolIntArray Entity::states_gets() const { PoolIntArray arr; arr.resize(EntityEnums::ENTITY_STATE_TYPE_INDEX_MAX); #if !GODOT4 PoolIntArray::Write w = arr.write(); #endif for (int i = 0; i < EntityEnums::ENTITY_STATE_TYPE_INDEX_MAX; ++i) { #if !GODOT4 w[i] = _s_states[i]; #else arr.write[i] = _s_states[i]; #endif } return arr; } void Entity::states_sets(const PoolIntArray &data) { ERR_FAIL_COND(data.size() <= EntityEnums::ENTITY_STATE_TYPE_INDEX_MAX); for (int i = 0; i < EntityEnums::ENTITY_STATE_TYPE_INDEX_MAX; ++i) { _s_states[i] = data[i]; } } //// Crafting System //// void Entity::craft_crequest(int id) { crafts(id); } void Entity::crafts(int id) { if (has_method("_crafts")) { call("_crafts", id); } } bool Entity::craft_hass_recipe(Ref craft_recipe) { for (int i = 0; i < _s_craft_recipes.size(); ++i) { if (_s_craft_recipes.get(i) == craft_recipe) { return true; } } return false; } bool Entity::craft_hass_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::craft_adds_recipe(Ref craft_recipe) { ERR_FAIL_COND(!craft_recipe.is_valid()); if (craft_hass_recipe(craft_recipe)) return; _s_craft_recipes.push_back(craft_recipe); emit_signal("crafts_recipe_added", this, craft_recipe); ORPC(craft_addc_recipe_id, craft_recipe->get_id()); } void Entity::craft_adds_recipe_id(int id) { ERR_FAIL_COND(!ESS::get_singleton()); if (craft_hass_recipe_id(id)) return; Ref craft_recipe = ESS::get_singleton()->get_resource_db()->get_craft_recipe(id); ERR_FAIL_COND(!craft_recipe.is_valid()); _s_craft_recipes.push_back(craft_recipe); if (ESS::get_singleton()->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_singleton()->getc_player_profile()->get_class_profile(_s_entity_data->get_path()); 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] == craft_recipe->get_path()) { found = true; break; } } if (!found) { recipes.push_back(craft_recipe->get_path()); class_profile->set_custom_data("recipes", recipes); } } else { Vector recipes; recipes.push_back(craft_recipe->get_path()); class_profile->set_custom_data("recipes", recipes); } } emit_signal("crafts_recipe_added", this, craft_recipe); ORPC(craft_addc_recipe_id, id); } void Entity::craft_removes_recipe(Ref craft_recipe) { for (int i = 0; i < _s_craft_recipes.size(); ++i) { if (_s_craft_recipes.get(i) == craft_recipe) { _s_craft_recipes.remove_at(i); break; } } emit_signal("crafts_recipe_removed", this, craft_recipe); ORPC(craft_removec_recipe, craft_recipe); } void Entity::craft_removes_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_at(i); break; } } emit_signal("crafts_recipe_removed", this, craft_recipe); ORPC(craft_removec_recipe_id, id); } Ref Entity::craft_gets_recipe(int index) { ERR_FAIL_INDEX_V(index, _s_craft_recipes.size(), Ref()); return _s_craft_recipes.get(index); } Ref Entity::craft_gets_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::craft_gets_recipe_count() { return _s_craft_recipes.size(); } bool Entity::craft_hasc_recipe(Ref craft_recipe) { for (int i = 0; i < _c_craft_recipes.size(); ++i) { if (_c_craft_recipes.get(i) == craft_recipe) { return true; } } return false; } bool Entity::craft_hasc_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::craft_addc_recipe(Ref craft_recipe) { if (craft_hasc_recipe(craft_recipe)) return; _c_craft_recipes.push_back(craft_recipe); emit_signal("ccraft_recipe_added", this, craft_recipe); } void Entity::craft_addc_recipe_id(int id) { ERR_FAIL_COND(!ESS::get_singleton()); if (craft_hasc_recipe_id(id)) return; Ref craft_recipe = ESS::get_singleton()->get_resource_db()->get_craft_recipe(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::craft_removec_recipe(Ref craft_recipe) { for (int i = 0; i < _c_craft_recipes.size(); ++i) { if (_c_craft_recipes.get(i) == craft_recipe) { _c_craft_recipes.remove_at(i); break; } } emit_signal("ccraft_recipe_removed", this, craft_recipe); } void Entity::craft_removec_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_at(i); break; } } emit_signal("ccraft_recipe_removed", this, craft_recipe); } Ref Entity::craft_getc_recipe(int index) { ERR_FAIL_INDEX_V(index, _c_craft_recipes.size(), Ref()); return _c_craft_recipes.get(index); } int Entity::craft_getc_recipe_count() { return _c_craft_recipes.size(); } Vector Entity::scraft_recipes_get() { VARIANT_ARRAY_GET(_s_craft_recipes); } void Entity::scraft_recipes_set(const Vector &resources) { VARIANT_ARRAY_SET(resources, _s_craft_recipes, CraftRecipe); } //// Stat System //// EntityStat Entity::get_stat(const int stat_id) const { ERR_FAIL_INDEX_V(stat_id, ESS::get_singleton()->stat_get_count(), EntityStat()); return _stats[stat_id]; } void Entity::set_stat(const int stat_id, const EntityStat &entry) { ERR_FAIL_INDEX(stat_id, ESS::get_singleton()->stat_get_count()); _stats.set(stat_id, entry); } bool Entity::stat_get_dirty(const int stat_id) const { ERR_FAIL_INDEX_V(stat_id, ESS::get_singleton()->stat_get_count(), false); return _stats[stat_id].dirty; } void Entity::stat_set_dirty(const int stat_id, const bool value) { ERR_FAIL_INDEX(stat_id, ESS::get_singleton()->stat_get_count()); _stats.write[stat_id].dirty = value; } float Entity::stat_get_base(const int stat_id) const { ERR_FAIL_INDEX_V(stat_id, ESS::get_singleton()->stat_get_count(), 0); return _stats[stat_id].base; } void Entity::stat_set_base(const int stat_id, const float value) { ERR_FAIL_INDEX(stat_id, ESS::get_singleton()->stat_get_count()); _stats.write[stat_id].base = value; stat_recalculate(stat_id); } void Entity::stat_mod_base(const int stat_id, const float value) { ERR_FAIL_INDEX(stat_id, ESS::get_singleton()->stat_get_count()); _stats.write[stat_id].base += value; stat_recalculate(stat_id); } float Entity::stat_get_base_calculated(const int stat_id) const { ERR_FAIL_INDEX_V(stat_id, ESS::get_singleton()->stat_get_count(), 0); return _stats[stat_id].base_calculated; } void Entity::stat_set_base_calculated(const int stat_id, const float value) { ERR_FAIL_INDEX(stat_id, ESS::get_singleton()->stat_get_count()); _stats.write[stat_id].base_calculated = value; stat_recalculate(stat_id); } float Entity::stat_get_bonus(const int stat_id) const { ERR_FAIL_INDEX_V(stat_id, ESS::get_singleton()->stat_get_count(), 0); return _stats[stat_id].bonus; } void Entity::stat_set_bonus(const int stat_id, const float value) { ERR_FAIL_INDEX(stat_id, ESS::get_singleton()->stat_get_count()); _stats.write[stat_id].bonus = value; stat_recalculate(stat_id); } void Entity::stat_mod_bonus(const int stat_id, const float value) { ERR_FAIL_INDEX(stat_id, ESS::get_singleton()->stat_get_count()); _stats.write[stat_id].bonus += value; stat_recalculate(stat_id); } float Entity::stat_get_percent(const int stat_id) const { ERR_FAIL_INDEX_V(stat_id, ESS::get_singleton()->stat_get_count(), 0); return _stats[stat_id].percent; } void Entity::stat_set_percent(const int stat_id, const float value) { ERR_FAIL_INDEX(stat_id, ESS::get_singleton()->stat_get_count()); _stats.write[stat_id].percent = value; stat_recalculate(stat_id); } void Entity::stat_mod_percent(const int stat_id, const float value) { ERR_FAIL_INDEX(stat_id, ESS::get_singleton()->stat_get_count()); _stats.write[stat_id].percent += value; stat_recalculate(stat_id); } void Entity::stat_mod(const int stat_id, const float base, const float bonus, const float percent) { ERR_FAIL_INDEX(stat_id, ESS::get_singleton()->stat_get_count()); _stats.write[stat_id].base += base; _stats.write[stat_id].bonus += bonus; _stats.write[stat_id].percent += percent; stat_recalculate(stat_id); } float Entity::stat_gets_current(const int stat_id) const { ERR_FAIL_INDEX_V(stat_id, ESS::get_singleton()->stat_get_count(), 0); return _stats[stat_id].scurrent; } void Entity::stat_sets_current(const int stat_id, const float value) { ERR_FAIL_INDEX(stat_id, ESS::get_singleton()->stat_get_count()); _stats.write[stat_id].scurrent = value; } float Entity::stat_getc_current(const int stat_id) const { ERR_FAIL_INDEX_V(stat_id, ESS::get_singleton()->stat_get_count(), 0); return _stats[stat_id].ccurrent; } void Entity::stat_setc_current(const int stat_id, const float value) { ERR_FAIL_INDEX(stat_id, ESS::get_singleton()->stat_get_count()); _stats.write[stat_id].ccurrent = value; notification_cstat_changed(stat_id, value); } void Entity::stat_recalculate(const int stat_id) { ERR_FAIL_INDEX(stat_id, ESS::get_singleton()->stat_get_count()); stat_sets_current(stat_id, (stat_get_base(stat_id) + stat_get_base_calculated(stat_id) + stat_get_bonus(stat_id)) * (stat_get_percent(stat_id) / 100.0)); stat_set_dirty(stat_id, true); notification_sstat_changed(stat_id, stat_gets_current(stat_id)); } void Entity::dies() { //serverside notification_sdeath(); //send an event to client VRPC(diec); //signal emit_signal("diesd", this); } void Entity::diec() { notification_cdeath(); } void Entity::notification_sstat_changed(const int statid, const float current) { for (int i = 0; i < _s_resources.size(); ++i) { _s_resources.get(i)->notification_sstat_changed(statid, current); } } void Entity::notification_cstat_changed(const int statid, const float current) { for (int i = 0; i < _c_resources.size(); ++i) { _c_resources.get(i)->notification_cstat_changed(statid, current); } } void Entity::ssend_stat(int id, int ccurrent) { ERR_FAIL_INDEX(id, ESS::get_singleton()->stat_get_count()); //Only the owner needs access to stats ORPC(creceive_stat, id, ccurrent); } void Entity::creceive_stat(int id, int ccurrent) { ERR_FAIL_INDEX(id, ESS::get_singleton()->stat_get_count()); stat_setc_current(id, ccurrent); } //// Equip Slots //// bool Entity::equip_should_deny(int equip_slot, Ref item) { if (_s_entity_controller == EntityEnums::ENITIY_CONTROLLER_AI && _s_ai.is_valid()) { if (_s_ai->equip_should_deny(this, equip_slot, item)) return true; } for (int i = 0; i < _s_auras.size(); ++i) { Ref ad = _s_auras.get(i); if (ad->get_aura()->equip_should_deny(ad, equip_slot, item)) return true; } if (has_method("_equip_should_deny")) if (call("_equip_should_deny", equip_slot, item)) return true; return false; } void Entity::equip_son_success(int equip_slot, Ref item, Ref old_item, int bag_slot) { if (_s_entity_controller == EntityEnums::ENITIY_CONTROLLER_AI && _s_ai.is_valid()) { _s_ai->equip_son_success(this, equip_slot, item, old_item, bag_slot); } for (int i = 0; i < _s_auras.size(); ++i) { Ref ad = _s_auras.get(i); ad->get_aura()->equip_son_success(ad, equip_slot, item, old_item, bag_slot); } if (has_method("_equip_son_success")) call("_equip_son_success", equip_slot, item, old_item, bag_slot); emit_signal("equip_son_success", this, equip_slot, item, old_item, bag_slot); } void Entity::equip_son_fail(int equip_slot, Ref item, Ref old_item, int bag_slot) { if (_s_entity_controller == EntityEnums::ENITIY_CONTROLLER_AI && _s_ai.is_valid()) { _s_ai->equip_son_fail(this, equip_slot, item, old_item, bag_slot); } for (int i = 0; i < _s_auras.size(); ++i) { Ref ad = _s_auras.get(i); ad->get_aura()->equip_son_fail(ad, equip_slot, item, old_item, bag_slot); } if (has_method("_equip_son_fail")) call("_equip_son_fail", equip_slot, item, old_item, bag_slot); emit_signal("equip_son_fail", this, equip_slot, item, old_item, bag_slot); } void Entity::equip_con_success(int equip_slot, Ref item, Ref old_item, int bag_slot) { if (_s_entity_controller == EntityEnums::ENITIY_CONTROLLER_AI && _s_ai.is_valid()) { _s_ai->equip_con_success(this, equip_slot, item, old_item, bag_slot); } for (int i = 0; i < _c_auras.size(); ++i) { Ref ad = _c_auras.get(i); ad->get_aura()->equip_con_success(ad, equip_slot, item, old_item, bag_slot); } if (has_method("_equip_con_success")) call("_equip_con_success", equip_slot, item, old_item, bag_slot); emit_signal("equip_con_success", this, equip_slot, item, old_item, bag_slot); } void Entity::equip_con_fail(int equip_slot, Ref item, Ref old_item, int bag_slot) { if (_s_entity_controller == EntityEnums::ENITIY_CONTROLLER_AI && _s_ai.is_valid()) { _s_ai->equip_con_fail(this, equip_slot, item, old_item, bag_slot); } for (int i = 0; i < _c_auras.size(); ++i) { Ref ad = _c_auras.get(i); ad->get_aura()->equip_con_fail(ad, equip_slot, item, old_item, bag_slot); } if (has_method("_equip_con_fail")) call("_equip_con_fail", equip_slot, item, old_item, bag_slot); emit_signal("equip_con_fail", this, equip_slot, item, old_item, bag_slot); } void Entity::equip_crequest(int equip_slot, int bag_slot) { RPCS(equips, equip_slot, bag_slot) } void Entity::equips(int equip_slot, int bag_slot) { call("_equips", equip_slot, bag_slot); } void Entity::_equips(int equip_slot, int bag_slot) { ERR_FAIL_INDEX(equip_slot, ESS::get_singleton()->equip_slot_get_count()); ERR_FAIL_COND(!_s_bag.is_valid()); Ref bag_item = _s_bag->get_item(bag_slot); Ref equipped_item = equip_gets_slot(equip_slot); if (!equip_can_equip_item(equip_slot, bag_item)) { ORPC(equip_cfail, equip_slot, bag_slot); return; } if (equip_should_deny(equip_slot, bag_item)) { ORPC(equip_cfail, equip_slot, bag_slot); return; } //check armor type //check required skills if (equipped_item.is_valid()) equip_deapplys_item(equipped_item); if (bag_item.is_valid()) equip_applys_item(bag_item); equip_sets_slot(equip_slot, bag_item); _s_bag->add_item_at(bag_slot, equipped_item, false); ORPC(equip_csuccess, equip_slot, bag_slot); } void Entity::equip_csuccess(int equip_slot, int bag_slot) { ERR_FAIL_INDEX(equip_slot, ESS::get_singleton()->equip_slot_get_count()); ERR_FAIL_COND(!_c_bag.is_valid()); Ref old_bag_item = _c_bag->get_item(bag_slot); Ref old_equipped_item = equip_getc_slot(equip_slot); _c_bag->add_item_at(bag_slot, old_equipped_item); equip_setc_slot(equip_slot, old_bag_item); if (old_equipped_item.is_valid()) equip_deapplyc_item(old_equipped_item); if (old_bag_item.is_valid()) equip_applyc_item(old_bag_item); equip_con_success(equip_slot, old_bag_item, old_equipped_item, bag_slot); } void Entity::equip_cfail(int equip_slot, int bag_slot) { ERR_FAIL_INDEX(equip_slot, ESS::get_singleton()->equip_slot_get_count()); ERR_FAIL_COND(!_c_bag.is_valid()); Ref bag_item = _c_bag->get_item(bag_slot); Ref equipped_item = equip_getc_slot(equip_slot); equip_con_fail(equip_slot, equipped_item, bag_item, bag_slot); } Ref Entity::equip_gets_slot(int index) { ERR_FAIL_INDEX_V(index, ESS::get_singleton()->equip_slot_get_count(), Ref()); return _s_equipment[index]; } void Entity::equip_sets_slot(int index, Ref item) { ERR_FAIL_INDEX(index, ESS::get_singleton()->equip_slot_get_count()); _s_equipment.write[index] = item; } Ref Entity::equip_getc_slot(int index) { ERR_FAIL_INDEX_V(index, ESS::get_singleton()->equip_slot_get_count(), Ref()); return _c_equipment[index]; } void Entity::equip_setc_slot(int index, Ref item) { ERR_FAIL_INDEX(index, ESS::get_singleton()->equip_slot_get_count()); _c_equipment.write[index] = item; } bool Entity::equip_can_equip_item(int equip_slot, Ref item) { return call("_equip_can_equip_item", equip_slot, item); } bool Entity::_equip_can_equip_item(int equip_slot, Ref item) { //deequip if (!item.is_valid()) return true; Ref it = item->get_item_template(); ERR_FAIL_COND_V(!it.is_valid(), false); return it->get_equip_slot() == equip_slot; } void Entity::equip_applys_item(Ref item) { call("_equip_applys_item", item); } void Entity::equip_deapplys_item(Ref item) { call("_equip_deapplys_item", item); } void Entity::_equip_applys_item(Ref item) { ERR_FAIL_COND(!item.is_valid()); Ref it = item->get_item_template(); ERR_FAIL_COND(!it.is_valid()); for (int i = 0; i < item->stat_modifier_get_count(); ++i) { int sid = item->stat_modifier_get_stat_id(i); stat_mod_base(sid, item->stat_modifier_get_base_mod(i)); stat_mod_bonus(sid, item->stat_modifier_get_bonus_mod(i)); stat_mod_percent(sid, item->stat_modifier_get_percent_mod(i)); } } void Entity::_equip_deapplys_item(Ref item) { ERR_FAIL_COND(!item.is_valid()); Ref it = item->get_item_template(); ERR_FAIL_COND(!it.is_valid()); for (int i = 0; i < item->stat_modifier_get_count(); ++i) { int sid = item->stat_modifier_get_stat_id(i); stat_mod_base(sid, -item->stat_modifier_get_base_mod(i)); stat_mod_bonus(sid, -item->stat_modifier_get_bonus_mod(i)); stat_mod_percent(sid, -item->stat_modifier_get_percent_mod(i)); } } void Entity::equip_applyc_item(Ref item) { call("_equip_applyc_item", item); } void Entity::equip_deapplyc_item(Ref item) { call("_equip_deapplyc_item", item); } void Entity::_equip_applyc_item(Ref item) { ERR_FAIL_COND(!item.is_valid()); Ref it = item->get_item_template(); ERR_FAIL_COND(!it.is_valid()); if (it->get_model_visual().is_valid() && INSTANCE_VALIDATE(_character_skeleton)) { if (_character_skeleton->has_method("add_model_visual")) _character_skeleton->call("add_model_visual", it->get_model_visual()); } } void Entity::_equip_deapplyc_item(Ref item) { ERR_FAIL_COND(!item.is_valid()); Ref it = item->get_item_template(); ERR_FAIL_COND(!it.is_valid()); if (it->get_model_visual().is_valid() && INSTANCE_VALIDATE(_character_skeleton)) { if (_character_skeleton->has_method("remove_model_visual")) _character_skeleton->call("remove_model_visual", it->get_model_visual()); } } //// Resources //// Ref Entity::resource_gets_index(int index) { ERR_FAIL_INDEX_V(index, _s_resources.size(), Ref()); return _s_resources.get(index); } Ref Entity::resource_gets_id(int id) { for (int i = EntityEnums::ENTITY_RESOURCE_INDEX_RESOURCES_BEGIN; i < _s_resources.size(); ++i) { Ref r = _s_resources.get(i); if (r->get_id() == id) { return r; } } return Ref(); } void Entity::resource_adds(Ref resource) { ERR_FAIL_COND(!resource.is_valid()); _s_resources.push_back(resource); resource->ons_added(this); notification_sentity_resource_added(resource); VRPCOBJP(resource_addc_rpc, _s_resources.size() - 1, JSON::stringify(resource->to_dict()), resource_addc, _s_resources.size() - 1, resource); } int Entity::resource_gets_count() { return _s_resources.size(); } void Entity::resource_removes(int index) { ERR_FAIL_INDEX(index, _s_resources.size()); Ref res = _s_resources.get(index); _s_resources.remove_at(index); notification_sentity_resource_removed(res); VRPC(resource_removec, index); } void Entity::resource_clears() { _s_resources.resize(EntityEnums::ENTITY_RESOURCE_INDEX_RESOURCES_BEGIN); VRPC(resource_clearc); } void Entity::resource_addc_rpc(int index, String data) { //Ref res; Dictionary dict = data_as_dict(data); /* String clsname = dict.get("id", "EntityResource"); res = Ref(Object::cast_to(ClassDB::instance(clsname))); ERR_FAIL_COND(!res.is_valid()); //res.instantiate(); String script_path = dict.get("script", ""); Ref