{"id":17017201,"url":"https://github.com/zsoltmolnarrr/spellpower","last_synced_at":"2025-04-12T09:31:12.984Z","repository":{"id":59943098,"uuid":"535315375","full_name":"ZsoltMolnarrr/SpellPower","owner":"ZsoltMolnarrr","description":"🔮 Spell Power entity attribute for magical abilities and items","archived":false,"fork":false,"pushed_at":"2024-09-14T21:41:12.000Z","size":826,"stargazers_count":10,"open_issues_count":5,"forks_count":8,"subscribers_count":3,"default_branch":"1.21.1","last_synced_at":"2024-10-31T11:36:41.369Z","etag":null,"topics":["artifact","attribute","combat","magic","minecraft","minecraft-mod","mod","spell"],"latest_commit_sha":null,"homepage":"https://www.curseforge.com/minecraft/mc-mods/spell-power","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ZsoltMolnarrr.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-11T14:00:05.000Z","updated_at":"2024-09-18T14:12:54.000Z","dependencies_parsed_at":"2024-10-14T06:36:15.575Z","dependency_job_id":"cc7daf04-eabb-48a1-a139-7c7274c6994c","html_url":"https://github.com/ZsoltMolnarrr/SpellPower","commit_stats":null,"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZsoltMolnarrr%2FSpellPower","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZsoltMolnarrr%2FSpellPower/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZsoltMolnarrr%2FSpellPower/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZsoltMolnarrr%2FSpellPower/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ZsoltMolnarrr","download_url":"https://codeload.github.com/ZsoltMolnarrr/SpellPower/tar.gz/refs/heads/1.21.1","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223510333,"owners_count":17157306,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["artifact","attribute","combat","magic","minecraft","minecraft-mod","mod","spell"],"created_at":"2024-10-14T06:36:00.482Z","updated_at":"2024-11-07T12:03:39.746Z","avatar_url":"https://github.com/ZsoltMolnarrr.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Spell Power](.github/icon_and_title.png)\n\n\n\u003cdiv align=\"center\"\u003e\n\n\u003ca href=\"\"\u003e![Java 17](https://img.shields.io/badge/Java%2017-ee9258?logo=coffeescript\u0026logoColor=ffffff\u0026labelColor=606060\u0026style=flat-square)\u003c/a\u003e\n\u003ca href=\"\"\u003e![Environment: Client \u0026 Server](https://img.shields.io/badge/environment-Client%20\u0026%20Server-1976d2?style=flat-square)\u003c/a\u003e\n\u003ca href=\"\"\u003e[![Discord](https://img.shields.io/discord/973561601519149057.svg?label=\u0026logo=discord\u0026logoColor=ffffff\u0026color=7389D8\u0026labelColor=6A7EC2\u0026style=flat-square)](https://discord.gg/KN9b3pjFTM)\u003c/a\u003e\n\n\u003c/div\u003e\n\n# 🔮️ Features\n\nThis library introduces new Entity Attributes for powering magical abilities, for the following magic types (schools):\n- 🔮 Arcane\n- 🔥 Fire\n- ❄️ Frost\n- 💚 Healing\n- ⚡️ Lightning\n- 👻 Soul\n- and the ones you want to add via Java API :)\n\n(Note: the design intent is to stay native to Minecraft, but establish Warcraft like magic schools. So no classic 4 element schools are implemented, besides fire.)\n\nThe library offers an API to query spell power of an entity (based on its attributes, status effects, enchantments), and provides critical strike chance and multiplier. Critical striking is completely rng based, powered by secondary attributes.\n\n## 📦 Content\n\n### Entity Attributes\n#### Spell Power\n- Represents power of spells with a number (somewhat analogous to `minecraft:generic_attack_damage` attribute), which serves as base to calculate spell damage\n- Attribute id (formula): `spell_power:SCHOOL` (for example: `spell_power:fire`)\n- A separate attribute exists for each specific magic school\n- `Base value = 0`\n\n#### Spell critical chance\n- Represents chance of critical striking with spells \n- Attribute id: `spell_power:critical_chance`\n- `Base value = 100` (technically) (this means 0% critical chance)\n- Example values: `120` ( = 20% critical chance), `200` ( = 100% critical chance)\n- All players have a `0.05, MULTIPLY_BASE` modifier by default, so the practical default value is `105` chance, making all spells `5%` critical chance by default\n\n#### Spell critical damage \n- Represents how much damage is increased when critical striking wit a spell\n- Attribute id: `spell_power:critical_damage`\n- `Base value = 100` (this means critical strikes don't do more damage than non-critical ones)\n- Example values: `150` ( = 150% critical damage), `200` ( = 200% critical chance)\n- All players have a `0.5, MULTIPLY_BASE` modifier by default, so the practical default value is 150, making all spells doe 1.5x damage on critical strike by default\n\n#### Spell haste\n- Represents the spell casting speed, (to be used to quicken spell casting or cooldowns by spell implementations)\n- Attribute id: `spell_power:haste`\n- `Base value = 100` (this means player casts spells at normal speed)\n- Players have no modifiers by default\n- Example values: `50` (50% faster spell casting), 200 (200% faster spell casting)\n\n### Status Effects\nEach introduced attribute (mentioned above), has with a matching status effect to boost them.\n\nThe id of these matches the with the id of the boosted attribute (for example: `spell_power:fire`, `spell_power:critical_chance`)\n\n(All status effects come with fancy icons 😍)\n\n### Enchantments\n- Universal Spell Power (named: \"Spell Power\"), increasing all spell damage\n- School limited Spell Power (for example: \"Sunfire\", increasing arcane and fire damage) \n- Secondary attribute enchantments (for example: \"Spell Critical Chance\")\n- \"Magic Protection\" (totally symmetric to Projectile Protection, but for magic)\n\nThese enchantments require the equipment to have at least some Spell Power attributes (such as + 1 Fire Spell Power).\n\nIn case of school limited enchantments the atttribute present must be relevant (for example Sunfire requires Arcane or Fire spell power to be present). \n\n(All enchantments are fully configurable, and come with descriptions)\n\nTo enable applying these enchantments to any item, add the item the one or more of the following tags:\n- `spell_power:enchantable/critical_damage`\n- `spell_power:enchantable/critical_chance`\n- `spell_power:enchantable/haste`\n- `spell_power:enchantable/spell_power_energize`\n- `spell_power:enchantable/spell_power_generic`\n- `spell_power:enchantable/spell_power_soulfrost`\n- `spell_power:enchantable/spell_power_specialized`\n- `spell_power:enchantable/spell_power_sunfire`\n\n# 🔧 Configuration\n\n**Server side** configuration can be found in the `config` directory, after running the game with the mod installed.\n\n# 🔨 Using it as a developer\n\n## Installation\n\nAdd this mod as dependency into your build.gradle file.\n\nRepository\n```groovy\nrepositories {\n    maven {\n        name = 'Modrinth'\n        url = 'https://api.modrinth.com/maven'\n        content {\n            includeGroup 'maven.modrinth'\n        }\n    }\n}\n```\n\n### Fabric workspace\n```groovy\ndependencies {\n    modImplementation(\"maven.modrinth:spell-power:${project.spell_power_version}\")\n}\n```\nIn `fabric.mod.json` add a dependency to the mod:\n```json\n  \"depends\": {\n    \"spell_power\": \"\u003e=VERSION\"\n  },\n```\n\n(Substitute `VERSION` with the name of the latest release available on [Modrinth](https://modrinth.com/mod/spell-power/versions))\n\n## Using attributes\n\nUse the attributes by directly referencing their original instance. For example: \n```java\n// ✅ \nSpellSchools.FIRE.attribute;\nSpellPowerMechanics.CRITICAL_CHANCE.attribute;\nSpellPowerMechanics.CRITICAL_DAMAGE.attribute;\nSpellPowerMechanics.HASTE.attribute;\n```\n\nAlternatively you can resolve them from attribute registry.\n\n(Note: power attributes of schools from third party developers may not be found this way, depending on which point they perform the registration.) \n\n```java\n// ✅\nRegistries.ATTRIBUTE.get(Identifier.of(\"spell_power:fire\"));\nRegistries.ATTRIBUTE.get(Identifier.of(\"spell_power:critical_chance\"));\n```\n\n### Query Spell Power\n\nUse the dedicated API (`SpellPower` class) to query spell power of an entity (only PlayerEntities are supported). This will produce a result with critical strike support, and will take into account:\n- the queried attribute\n- critical strike related attributes (chance and multiplier)\n- status effects \n- enchantments\n\n```java\n// Given `player` is a PlayerEntity\n// ✅\nvar result = SpellPower.getSpellPower(player, SpellSchools.FIRE);\ndouble value = result.randomValue(); // Randomly produces a critical strike or a base value (based on attributes)\ndouble forcedCritValue = result.forcedCriticalValue(); // Forces a critical strike value\ndobule forcedBaseValue = result.nonCriticalValue(); // Forces a non-critical strike value\n```\n\nThe value received is an abstract number. Spell implementations should calculate with this value using an arbitrary formula. This typically means some linear scaling. For example:\n- A quickly casted spell named _Scorch_ might apply a low multiplier. `var damage = result.randomValue() * 0.5;`\n- A slowly casted spell named _Fireball_ might apply a higher multiplier. `var damage = result.randomValue() * 0.9F;`\n\nThe total value of Spell Power queried completely depends on the content mods.\n\nDo not use vanilla API to query Spell Power values, as it doesn't take into account any of the above mentioned factors.\n```java\n// 🚫\nplayer.getAttributeValue(SpellSchools.FIRE.attribute);\n```\n\n### Adding attributes modifiers to equipment\n\nAdd attributes modifiers to your equipment items, to increase spell power of the player. For example:\n```java\n// Given: `ImmutableMultimap.Builder\u003cEntityAttribute, EntityAttributeModifier\u003e builder`\nvar fireSpellPower = 1; // + 1 Fire Spell Power\nbuilder.put(SpellSchools.FIRE.attribute,\n    new EntityAttributeModifier(\n        SomeUUID,\n        \"Spell Power\",\n        fireSpellPower,\n        EntityAttributeModifier.Operation.ADDITION\n    )\n);\n\nvar haste = 0.1; // +10% Spell Haste\nbuilder.put(SpellPowerMechanics.HASTE.attribute,\n    new EntityAttributeModifier(\n        SomeUUID,\n        \"Spell Haste\",\n        haste,\n        EntityAttributeModifier.Operation.MULTIPLY_BASE\n    )\n);\n\n\nvar critChance = 0.01; // +1% Spell Crit Chance\nbuilder.put(SpellPowerMechanics.CRITICAL_CHANCE.attribute,\n    new EntityAttributeModifier(\n        SomeUUID,\n        \"Spell Crit Chance\",\n        critChance,\n        EntityAttributeModifier.Operation.MULTIPLY_BASE\n    )\n);\n\nvar critDamage = 0.5; // +50% Spell Crit Damage\nbuilder.put(SpellPowerMechanics.CRITICAL_DAMAGE.attribute,\n    new EntityAttributeModifier(\n        SomeUUID,\n        \"Crit Damage\",\n        critDamage,\n        EntityAttributeModifier.Operation.MULTIPLY_BASE\n    )\n);\n```\n\n**How big bonuses should be used?**\n\nAs long as the user experience is intended to be Vanilla friendly, it is recommended to keep your Spell Power bonuses roughly in the same ballpark as vanilla `attack_damage` attribute. For example:\n- A staff might have + 4 Fire Spell Power\n\n### Vulnerabilities\n\nVulnerabilities are a way to increase spell damage taken by an entity. They can be attached to any arbitrary trait or object of an entity.\n\nA vulnerability can modify the following for a specific entity:\n- Total spell damage taken\n- Critical strike chance against the entity\n- Critical strike damage against the entity\n\nThis library implements Vulnerabilities as status effects by default.\n\nThe following example shows how _Frozen_ status effect increases critical strike chance against frozen the entity.\n```java\n// 1. Create a StatusEffect subclassing SpellVulnerabilityStatusEffect, or implementing `VulnerabilityEffect`\npublic class FrozenStatusEffect extends SpellVulnerabilityStatusEffect { ... }\n\n// 2. Create your status effect instance and configure it\npublic static StatusEffect frozen = new FrozenStatusEffect(StatusEffectCategory.HARMFUL, 0x99ccff)\n        .setVulnerability(SpellSchools.FROST, new SpellPower.Vulnerability(0, 1F, 0F));\n\n// 3. Register your status effect as usual\n```\n\nTo add a completely custom vulnerability mechanic, the following can be used:\n```java\nSpellPower.vulnerabilitySources.add(query -\u003e {\n    var target = query.entity();\n    // My logic\n    return List.of(...)\n})\n```\n\n### Adopting Spell Haste\n\nSpell Haste represents the casting speed of spells.\n\nIf implementing completely custom spells and want to calculate with Spell Haste attribute of players keep reading.\n\nTo retrieve the Spell Haste value of a player, use the following API:\n```java\n// Given `player` is a PlayerEntity\nfloat haste = SpellPower.getHaste(player, SpellSchools.FIRE);\n```\n\nThis value represents a relative casting speed. For example:\n- When players have no haste bonus (so default attribute value) it returns `1.0`\n- When players have 50% haste bonus (so attribute value of 150) it returns `1.5`\n\nHaste can be calculated with using arbitrary formula. But the typical recommendation is the following:\n```java\n// Given `myCooldownDuration` is a valid number that presrents the duration of the cooldown\nfloat hasteAffectedCooldownDuration = hasteAffectedValue(caster, myCooldownDuration);\n// Given `mySpellCastDuration` is a valid number that presrents the duration of the spell cast\nfloat hasteAffectedSpellCastDuration = hasteAffectedValue(caster, mySpellCastDuration);\n\nfloat hasteAffectedValue(PlayerEntity caster, float value) {\n    var haste = (float) SpellPower.getHaste(caster, SpellSchools.FIRE);\n    return value / haste;\n}\n```\n\n## Creating custom Spell Schools\n\nTo create a new spell school:\n1. Create `SpellSchool` instance\n2. Add its power sources (how damage, critical chance, critical damage, haste is calculated)\n3. Register the school\n\nIn case you want an additional magic type, all of this can be done using the provided helper methods.\n\nExample: Creating and registering \"Blood\" magic\n```java\npublic class BloodMagicMod {\n    // Creates school with the id of `spell_power:blood`, default namespace: `spell_power`\n    public static final SpellSchool BLOOD = SpellSchools.createMagic(\"blood\", 0x7e1c07);\n}\n``` \n\nFor regular `magic` schools, it is strongly recommended to perform the registration with the following mixin, to ensure:\n- Related attribute is generated and registered at the correct point\n- Related status effect is generated and registered at the correct point\n```java\n@Mixin(value = SpellSchools.class)\npublic class SpellSchoolsMixin {\n    @Inject(method = \"\u003cclinit\u003e\", at = @At(\"TAIL\"))\n    private static void static_tail_BloodMagic(CallbackInfo ci) {\n        SpellSchool.register(BloodMagicMod.BLOOD); // Trigger registration\n    }\n}\n```\n\nAssets to add for new schools:\n- Translation for school powering attribute (`\"attribute.name.NAMESAPCE.MY_SCHOOL\" : \"My School Spell Power\",`)\n- Translation for school boosting status effect (`\"effect.NAMESAPCE.MY_SCHOOL\" : \"My School Power\"`)\n- Icon for school boosting status effect (`textures/mob_effect/MY_SCHOOL.png`)\n\nNote: translation for commonly occurring magic types are already included.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzsoltmolnarrr%2Fspellpower","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzsoltmolnarrr%2Fspellpower","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzsoltmolnarrr%2Fspellpower/lists"}