diff --git a/data/mods/Aftershock/spells.json b/data/mods/Aftershock/spells.json
index 4cd9696fe592c..d6e86fc23f81f 100644
--- a/data/mods/Aftershock/spells.json
+++ b/data/mods/Aftershock/spells.json
@@ -194,33 +194,15 @@
"description": "Your weapon releases a searing fan of plasma.",
"effect": "attack",
"shape": "cone",
- "extra_effects": [ { "id": "spell_fusion_fan_bash" } ],
"field_id": "fd_rad_glimmer",
"min_field_intensity": 3,
"max_field_intensity": 9,
"valid_targets": [ "hostile", "ally", "ground" ],
- "flags": [ "LOUD", "NO_EXPLOSION_SFX" ],
+ "flags": [ "LOUD", "NO_EXPLOSION_SFX", "RANDOM_DAMAGE", "IGNORE_WALLS" ],
"min_damage": 15,
"max_damage": 15,
- "min_aoe": 15,
- "max_aoe": 15,
- "min_range": 10,
- "max_range": 10,
- "difficulty": 1,
- "sound_description": "fzzzt",
- "damage_type": "afs_plasma"
- },
- {
- "id": "spell_fusion_fan_bash",
- "type": "SPELL",
- "name": "Plasma fan",
- "description": "Damages terrain within the plasma fan.",
- "effect": "bash",
- "shape": "cone",
- "valid_targets": [ "ground" ],
- "flags": [ "SILENT", "NO_EXPLOSION_SFX", "IGNORE_WALLS", "RANDOM_DAMAGE" ],
- "min_damage": 15,
- "max_damage": 60,
+ "min_bash_scaling": 1,
+ "max_bash_scaling": 4,
"min_aoe": 15,
"max_aoe": 15,
"min_range": 10,
diff --git a/data/mods/Magiclysm/Spells/attunements/Earth_Elemental.json b/data/mods/Magiclysm/Spells/attunements/Earth_Elemental.json
index 4ad2a6c97de4e..e7f7c830227ea 100644
--- a/data/mods/Magiclysm/Spells/attunements/Earth_Elemental.json
+++ b/data/mods/Magiclysm/Spells/attunements/Earth_Elemental.json
@@ -18,6 +18,9 @@
"min_damage": 20,
"damage_increment": 4.0,
"max_damage": 160,
+ "min_bash_scaling": 1.5,
+ "bash_scaling_increment": -0.007,
+ "max_bash_scaling": 1.25,
"min_aoe": 0,
"max_aoe": 35,
"aoe_increment": 1,
@@ -32,7 +35,7 @@
"sound_id": "earth_spell",
"sound_variant": "strong",
"energy_source": "MANA",
- "extra_effects": [ { "id": "quake_transform" }, { "id": "quake_shake" }, { "id": "eoc_evocation_setup", "hit_self": true } ]
+ "extra_effects": [ { "id": "quake_transform" }, { "id": "eoc_evocation_setup", "hit_self": true } ]
},
{
"id": "quake_transform",
@@ -52,23 +55,6 @@
"aoe_increment": 1,
"max_level": 35
},
- {
- "id": "quake_shake",
- "type": "SPELL",
- "name": "Quake Earthquake",
- "description": "Destroy furniture and terrain nearby.",
- "valid_targets": [ "hostile", "ground" ],
- "flags": [ "EVOCATION_SPELL", "SILENT", "NO_EXPLOSION_SFX", "IGNORE_WALLS" ],
- "effect": "bash",
- "shape": "blast",
- "min_damage": 30,
- "max_damage": 200,
- "damage_increment": 5,
- "min_aoe": 0,
- "max_aoe": 35,
- "aoe_increment": 1,
- "max_level": 35
- },
{
"id": "rock_blast",
"type": "SPELL",
diff --git a/data/mods/Magiclysm/Spells/druid.json b/data/mods/Magiclysm/Spells/druid.json
index a5498f7d0053d..d274bb84d0fd1 100644
--- a/data/mods/Magiclysm/Spells/druid.json
+++ b/data/mods/Magiclysm/Spells/druid.json
@@ -619,11 +619,7 @@
"name": "Cause Rot",
"description": "A spell from a darker sect of druidry, created to forcibly begin the circle of life anew. For without rot, you cannot have growth. Affects a huge area, but is indiscriminate; even rusting machines into nothing but dust and slow both in casting and effect. Once lost entirely to the passage of time, this spell was thought to be no more than a myth, the stuff of fairy tales, albeit grim ones.",
"effect": "attack",
- "extra_effects": [
- { "id": "druid_cause_rot_terrain" },
- { "id": "druid_cause_rot_terrain_bash" },
- { "id": "eoc_channeling_setup", "hit_self": true }
- ],
+ "extra_effects": [ { "id": "druid_cause_rot_terrain" }, { "id": "eoc_channeling_setup", "hit_self": true } ],
"shape": "blast",
"valid_targets": [ "hostile", "ground" ],
"flags": [ "CHANNELING_SPELL", "SOMATIC", "NO_PROJECTILE", "CONCENTRATE", "VERBAL", "IGNORE_WALLS" ],
@@ -643,6 +639,8 @@
"aoe_increment": 1.8,
"min_damage": 1,
"max_damage": 1,
+ "min_bash_scaling": 20,
+ "max_bash_scaling": 170,
"min_dot": 1,
"max_dot": 5,
"dot_increment": 0.2,
@@ -666,24 +664,6 @@
"max_aoe": 50,
"aoe_increment": 1.8
},
- {
- "id": "druid_cause_rot_terrain_bash",
- "type": "SPELL",
- "name": "Cause Rot Terrain Bash",
- "description": "The bash terrain effect of the Cause Rot spell. It's a bug if you have it directly. It would be nice if this could take effect gradually but that's now how terrain bash works.",
- "effect": "bash",
- "shape": "blast",
- "valid_targets": [ "hostile", "ground" ],
- "flags": [ "CHANNELING_SPELL", "SOMATIC", "NO_PROJECTILE", "CONCENTRATE", "VERBAL", "IGNORE_WALLS" ],
- "max_level": 25,
- "spell_class": "DRUID",
- "min_aoe": 5,
- "max_aoe": 50,
- "aoe_increment": 1.8,
- "min_damage": 20,
- "max_damage": 170,
- "damage_increment": 6
- },
{
"id": "druid_healing",
"type": "SPELL",
diff --git a/data/mods/MindOverMatter/powers/telekinesis.json b/data/mods/MindOverMatter/powers/telekinesis.json
index d4ae98b479d66..9901ee7cdb3e5 100644
--- a/data/mods/MindOverMatter/powers/telekinesis.json
+++ b/data/mods/MindOverMatter/powers/telekinesis.json
@@ -532,7 +532,6 @@
"flags": [ "PSIONIC", "CONCENTRATE", "NO_PROJECTILE", "RANDOM_DAMAGE", "NO_HANDS", "NO_LEGS" ],
"difficulty": 5,
"max_level": { "math": [ "int_to_level(1)" ] },
- "extra_effects": [ { "id": "tele_mindhammer_bash", "hit_self": false, "max_level": 20 } ],
"damage_type": "psi_telekinetic_damage",
"effect": "attack",
"shape": "blast",
@@ -546,6 +545,8 @@
"( (u_spell_level('telekinetic_hammer') * 3.5) + 55) * (scaling_factor(u_val('intelligence') ) ) * u_nether_attunement_power_scaling"
]
},
+ "min_bash_scaling": 1,
+ "max_bash_scaling": 1,
"min_range": {
"math": [
"min( (( (u_spell_level('telekinetic_hammer') * 0.9) + 3) * (scaling_factor(u_val('intelligence') ) ) * u_nether_attunement_power_scaling), 70)"
@@ -563,36 +564,6 @@
"sound_description": "a heavy thud!",
"ignored_monster_species": [ "PSI_NULL" ]
},
- {
- "id": "tele_mindhammer_bash",
- "type": "SPELL",
- "name": "Mindhammer Ground damage",
- "description": "Damages ground when you use Mindhammer. If you have this you debugged it in.",
- "teachable": false,
- "valid_targets": [ "ground" ],
- "spell_class": "TELEKINETIC",
- "flags": [ "PSIONIC", "RANDOM_DAMAGE", "IGNORE_WALLS", "NO_PROJECTILE" ],
- "effect": "bash",
- "shape": "blast",
- "damage_type": "bash",
- "min_damage": {
- "math": [
- "( (u_spell_level('telekinetic_hammer') * 1.5) + 25) * (scaling_factor(u_val('intelligence') ) ) * u_nether_attunement_power_scaling"
- ]
- },
- "max_damage": {
- "math": [
- "( (u_spell_level('telekinetic_hammer') * 3) + 55) * (scaling_factor(u_val('intelligence') ) ) * u_nether_attunement_power_scaling"
- ]
- },
- "min_range": {
- "math": [
- "min( (( (u_spell_level('telekinetic_hammer') * 0.9) + 3) * (scaling_factor(u_val('intelligence') ) ) * u_nether_attunement_power_scaling), 70)"
- ]
- },
- "max_range": 70,
- "ignored_monster_species": [ "PSI_NULL" ]
- },
{
"id": "telekinetic_vehicle_lift",
"type": "SPELL",
@@ -676,7 +647,7 @@
"description": "A burst of telekinetic force shatters the terrain at the target location, as well as anything caught inside.",
"message": "You indiscriminately blast your targets!",
"teachable": false,
- "valid_targets": [ "ally", "hostile", "ground" ],
+ "valid_targets": [ "ally", "hostile", "item", "ground" ],
"spell_class": "TELEKINETIC",
"skill": "metaphysics",
"flags": [
@@ -693,8 +664,8 @@
],
"difficulty": 7,
"max_level": { "math": [ "int_to_level(1)" ] },
- "effect": "bash",
- "extra_effects": [ { "id": "tele_explosion_damage", "hit_self": false, "max_level": 20 } ],
+ "effect": "attack",
+ "damage_type": "psi_telekinetic_damage",
"shape": "blast",
"min_damage": {
"math": [
@@ -706,6 +677,8 @@
"( (u_spell_level('telekinetic_explosion') * 7.5) + 99) * (scaling_factor(u_val('intelligence') ) ) * u_nether_attunement_power_scaling"
]
},
+ "min_bash_scaling": 1,
+ "max_bash_scaling": 1,
"min_range": {
"math": [
"min( (( (u_spell_level('telekinetic_explosion') * 0.9) + 4) * (scaling_factor(u_val('intelligence') ) ) * u_nether_attunement_power_scaling), 60)"
@@ -729,42 +702,6 @@
"sound_description": "a loud crash!",
"ignored_monster_species": [ "PSI_NULL" ]
},
- {
- "id": "tele_explosion_damage",
- "type": "SPELL",
- "name": "Wrecking Ball Enemy damage",
- "description": "Damages enemies when you use Wrecking Ball on the ground. If you have this you debugged it in.",
- "valid_targets": [ "ally", "hostile", "item", "ground" ],
- "teachable": false,
- "spell_class": "TELEKINETIC",
- "flags": [ "PSIONIC", "LOUD", "RANDOM_DAMAGE", "IGNORE_WALLS" ],
- "effect": "attack",
- "shape": "blast",
- "damage_type": "psi_telekinetic_damage",
- "min_damage": {
- "math": [
- "( (u_spell_level('telekinetic_explosion') * 3) + 22) * (scaling_factor(u_val('intelligence') ) ) * u_nether_attunement_power_scaling"
- ]
- },
- "max_damage": {
- "math": [
- "( (u_spell_level('telekinetic_explosion') * 7.5) + 99) * (scaling_factor(u_val('intelligence') ) ) * u_nether_attunement_power_scaling"
- ]
- },
- "min_range": {
- "math": [
- "min( (( (u_spell_level('telekinetic_explosion') * 0.9) + 4) * (scaling_factor(u_val('intelligence') ) ) * u_nether_attunement_power_scaling), 60)"
- ]
- },
- "max_range": 60,
- "min_aoe": {
- "math": [
- "min( (( (u_spell_level('telekinetic_explosion') * 0.3) + 2) * (scaling_factor(u_val('intelligence') ) ) * u_nether_attunement_power_scaling), 30)"
- ]
- },
- "max_aoe": 30,
- "ignored_monster_species": [ "PSI_NULL" ]
- },
{
"id": "telekinetic_levitation",
"type": "SPELL",
diff --git a/data/mods/Xedra_Evolved/monsters/monster_spells.json b/data/mods/Xedra_Evolved/monsters/monster_spells.json
index 7ec53e8befce9..32aee2ace37d5 100644
--- a/data/mods/Xedra_Evolved/monsters/monster_spells.json
+++ b/data/mods/Xedra_Evolved/monsters/monster_spells.json
@@ -390,9 +390,11 @@
"min_damage": 20,
"max_damage": 50,
"damage_increment": 6,
+ "min_bash_scaling": 2,
+ "max_bash_scaling": 10,
+ "bash_scaling_increment": 1,
"min_range": 1,
- "max_range": 1,
- "extra_effects": [ { "id": "point_blank_bash" } ]
+ "max_range": 1
},
{
"id": "mon_luna_attuned_revenant_beam",
diff --git a/data/mods/Xedra_Evolved/monsters/monsterattacks.json b/data/mods/Xedra_Evolved/monsters/monsterattacks.json
index abec12b6b8100..733dcef10a5e5 100644
--- a/data/mods/Xedra_Evolved/monsters/monsterattacks.json
+++ b/data/mods/Xedra_Evolved/monsters/monsterattacks.json
@@ -182,30 +182,15 @@
"flags": [ "SILENT", "IGNORE_WALLS", "RANDOM_AOE", "RANDOM_DAMAGE" ],
"min_damage": 60,
"max_damage": 150,
+ "min_bash_scaling": 3,
+ "max_bash_scaling": 4,
"min_range": 9,
"max_range": 9,
"min_aoe": 25,
"max_aoe": 50,
"damage_type": "pure",
"sound_description": "a loud whisper",
- "extra_effects": [ { "id": "sapient_light_bash" }, { "id": "sapient_light_damage_player" } ]
- },
- {
- "id": "sapient_light_bash",
- "type": "SPELL",
- "name": "Sapient Bash",
- "description": "Bash some terrain. You can't see it except in debug mode.",
- "message": "",
- "effect": "bash",
- "shape": "cone",
- "valid_targets": [ "hostile", "ground", "item" ],
- "flags": [ "LOUD", "IGNORE_WALLS", "NO_EXPLOSION_SFX", "RANDOM_AOE", "RANDOM_DAMAGE" ],
- "min_damage": 180,
- "max_damage": 600,
- "min_range": 9,
- "max_range": 9,
- "min_aoe": 25,
- "max_aoe": 50
+ "extra_effects": [ { "id": "sapient_light_damage_player" } ]
},
{
"id": "sapient_light_damage_player",
@@ -219,12 +204,13 @@
"flags": [ "SILENT", "IGNORE_WALLS", "PERCENTAGE_DAMAGE", "NO_EXPLOSION_SFX" ],
"min_damage": 34,
"max_damage": 34,
+ "min_bash_scaling": 5.3,
+ "max_bash_scaling": 17.6,
"min_range": 9,
"max_range": 9,
"min_aoe": 50,
"max_aoe": 50,
- "damage_type": "pure",
- "extra_effects": [ { "id": "sapient_light_bash" } ]
+ "damage_type": "pure"
},
{
"type": "SPELL",
diff --git a/data/mods/Xedra_Evolved/mutations/paraclesians/undine_mutation_spells.json b/data/mods/Xedra_Evolved/mutations/paraclesians/undine_mutation_spells.json
index 1c526a06ce64f..a3a302e0fd5c0 100644
--- a/data/mods/Xedra_Evolved/mutations/paraclesians/undine_mutation_spells.json
+++ b/data/mods/Xedra_Evolved/mutations/paraclesians/undine_mutation_spells.json
@@ -813,13 +813,12 @@
"max_level": { "math": [ "str_to_level(1)" ] },
"effect": "attack",
"effect_str": "downed",
- "extra_effects": [
- { "id": "undine_tidal_wave_spell_bash", "hit_self": false },
- { "id": "undine_tidal_wave_spell_push", "hit_self": false }
- ],
+ "extra_effects": [ { "id": "undine_tidal_wave_spell_push", "hit_self": false } ],
"shape": "line",
"min_damage": { "math": [ "( (u_spell_level('undine_tidal_wave_spell') * 3) + 40) * (scaling_factor(u_val('strength') ) )" ] },
"max_damage": { "math": [ "( (u_spell_level('undine_tidal_wave_spell') * 9) + 100) * (scaling_factor(u_val('strength') ) )" ] },
+ "min_bash_scaling": 1.14,
+ "max_bash_scaling": 1.25,
"damage_type": "bash",
"min_duration": 200,
"max_duration": 900,
@@ -839,29 +838,6 @@
"final_casting_time": 50,
"casting_time_increment": -12
},
- {
- "id": "undine_tidal_wave_spell_bash",
- "type": "SPELL",
- "name": "Tidal Wave Bash",
- "description": "The Bash effect of the Tidal Wave spell. It's a bug if you have it directly.",
- "teachable": false,
- "valid_targets": [ "ground", "hostile" ],
- "spell_class": "UNDINE",
- "flags": [ "LOUD", "RANDOM_DAMAGE" ],
- "max_level": { "math": [ "str_to_level(1)" ] },
- "effect": "bash",
- "shape": "line",
- "min_damage": { "math": [ "( (u_spell_level('undine_tidal_wave_spell') * 3) + 35) * (scaling_factor(u_val('strength') ) )" ] },
- "max_damage": { "math": [ "( (u_spell_level('undine_tidal_wave_spell') * 7) + 80) * (scaling_factor(u_val('strength') ) )" ] },
- "min_range": {
- "math": [ "min( (( (u_spell_level('undine_tidal_wave_spell') * 0.75) + 4) * (scaling_factor(u_val('strength') ) )), 30)" ]
- },
- "max_range": 50,
- "min_aoe": {
- "math": [ "min( (( (u_spell_level('undine_tidal_wave_spell') * 0.3) + 2) * (scaling_factor(u_val('strength') ) )), 6)" ]
- },
- "max_aoe": 6
- },
{
"id": "undine_tidal_wave_spell_push",
"type": "SPELL",
diff --git a/data/mods/Xedra_Evolved/spells/dreamer_spells.json b/data/mods/Xedra_Evolved/spells/dreamer_spells.json
index e743d4c934fa8..9758ba0dc199a 100644
--- a/data/mods/Xedra_Evolved/spells/dreamer_spells.json
+++ b/data/mods/Xedra_Evolved/spells/dreamer_spells.json
@@ -389,26 +389,13 @@
"flags": [ "SILENT", "IGNORE_WALLS", "NO_EXPLOSION_SFX", "RANDOM_DAMAGE" ],
"min_damage": 360,
"max_damage": 500,
+ "min_bash_scaling": 1,
+ "max_bash_scaling": 1,
"min_range": 1,
"max_range": 1,
"message": "",
"damage_type": "bash",
"sound_description": "a smash",
- "extra_effects": [ { "id": "constructed_hammer_bash" } ]
- },
- {
- "id": "constructed_hammer_bash",
- "type": "SPELL",
- "name": "Constructed Hammer Bash",
- "description": "Bash some terrain. You can't see it except in debug mode.",
- "effect": "bash",
- "shape": "cone",
- "valid_targets": [ "hostile", "ground" ],
- "flags": [ "SILENT", "IGNORE_WALLS", "NO_EXPLOSION_SFX", "RANDOM_DAMAGE" ],
- "min_damage": 360,
- "max_damage": 500,
- "min_range": 1,
- "max_range": 1,
"extra_effects": [ { "id": "constructed_hammer_self_destruct" } ]
},
{
diff --git a/data/mods/Xedra_Evolved/spells/eater_spells.json b/data/mods/Xedra_Evolved/spells/eater_spells.json
index 4f967783e6959..daecffda062e4 100644
--- a/data/mods/Xedra_Evolved/spells/eater_spells.json
+++ b/data/mods/Xedra_Evolved/spells/eater_spells.json
@@ -560,23 +560,7 @@
"min_damage": 20,
"max_damage": 250,
"damage_increment": 6,
- "min_range": 1,
- "max_range": 1,
- "extra_effects": [ { "id": "point_blank_bash" } ]
- },
- {
- "id": "point_blank_bash",
- "type": "SPELL",
- "name": "Point Blank Bash",
- "description": "Additional terrain damage.",
- "valid_targets": [ "ground" ],
- "effect": "bash",
- "shape": "blast",
- "flags": [ "SILENT", "NO_EXPLOSION_SFX" ],
- "max_level": { "math": [ "eater_level(1)" ] },
- "min_damage": 40,
- "max_damage": 500,
- "damage_increment": 10,
+ "min_bash_scaling": 2,
"min_range": 1,
"max_range": 1
}
diff --git a/data/mods/Xedra_Evolved/spells/item_spells.json b/data/mods/Xedra_Evolved/spells/item_spells.json
index 05eabcbe9fe5c..7d1ae31fb71c4 100644
--- a/data/mods/Xedra_Evolved/spells/item_spells.json
+++ b/data/mods/Xedra_Evolved/spells/item_spells.json
@@ -405,34 +405,17 @@
"description": "Having this spell is a bug. And casting it is lethal",
"message": "The location the grenade occupied is instantly overwhelmed with sounds and colors you've never felt before as space warps in impossible ways. Whatever used to be there is now gone.",
"effect": "attack",
- "extra_effects": [
- { "id": "netherium_warp_grenade_detonation_terrain", "max_level": 0 },
- { "id": "netherium_warp_grenade_detonation_portal", "max_level": 0 }
- ],
+ "extra_effects": [ { "id": "netherium_warp_grenade_detonation_portal", "max_level": 0 } ],
"shape": "blast",
- "valid_targets": [ "self", "hostile", "ally" ],
+ "valid_targets": [ "self", "hostile", "ally", "ground" ],
"min_damage": 1000,
"max_damage": 1000,
+ "min_bash_scaling": 10,
"min_aoe": 2,
"max_aoe": 5,
"damage_type": "pure",
"flags": [ "NO_FAIL", "NO_HANDS", "NO_LEGS", "NON_MAGICAL", "RANDOM_AOE", "PERCENTAGE_DAMAGE", "IGNORE_WALLS" ]
},
- {
- "id": "netherium_warp_grenade_detonation_terrain",
- "type": "SPELL",
- "name": "Netherium Warp Detonation - Terrain",
- "description": "Having this spell is a bug. Cast to forget about your surroundings",
- "effect": "bash",
- "shape": "blast",
- "valid_targets": [ "ground" ],
- "flags": [ "NO_FAIL", "NO_HANDS", "NO_LEGS", "NON_MAGICAL", "RANDOM_AOE", "IGNORE_WALLS" ],
- "min_damage": 10000,
- "max_damage": 10000,
- "min_aoe": 2,
- "max_aoe": 5,
- "damage_type": "bash"
- },
{
"id": "netherium_warp_grenade_detonation_portal",
"type": "SPELL",
diff --git a/doc/MAGIC.md b/doc/MAGIC.md
index c3b5e6538b2d9..2f4062f2a833c 100644
--- a/doc/MAGIC.md
+++ b/doc/MAGIC.md
@@ -231,6 +231,7 @@ Field group | Description | Example
`min_accuracy`, `max_accuracy`, `accuracy_increment` | Accuracy of the spell. -20 accuracy will cause it to always miss, 20 will cause it always hit. Currently doesn't work. | "min_accuracy" -20,
"max_accuracy": 20,
"accuracy_increment": 1.5
`min_dot`, `max_dot`, `dot_increment` | Short for "damage over time". Similar to damage, positive values hurt while negative values heal.
Note: dot values are rounded up, so 1.1 will be 2. | "min_dot": 0,
"max_dot": 2,
"dot_increment": 0.1,
`min_pierce`, `max_pierce`, `pierce_increment` | Armor "piercing", how much armor of the same `damage_type` the spell will ignore. | "min_pierce": 0,
"max_pierce": 1,
"pierce_increment": 0.1,
+`min_bash_scaling`, `max_bash_scaling`, `bash_scaling_increment` | Converts a spell with the "attack" effect's damage into the scaling amount of terrain damage. | "min_bash_scaling": 1.0,
"max_bash_scaling": 2.0,
"bash_scaling_increment": 0.1,
`base_casting_time`, `final_casting_time`, `casting_time_increment` | Time the caster spends when casting the spell. Similar to duration, it's written in moves, which allows spells to be casted in fractions of a second. Ignored for monsters and items that cast spells. If several spells are chained, only the first one will apply the cost.
Note: The casting time is not shown to the player (e.g. a cast of 300 will behave as if the player waits for 3 turns). | "base_casting_time": 1000,
"final_casting_time": 100,
"casting_time_increment": -50,
`base_energy_cost`, `final_energy_cost`, `energy_increment` | Amount of energy spent for cast. If several spells are chained, only the first one will apply the cost. Ignored for monsters and items that cast spells. | "base_energy_cost": 30,
"final_energy_cost": 100,
"energy_increment": -6,
`field_id`, `field_chance`, `min_field_intensity`, `max_field_intensity`, `field_intensity_increment`, `field_intensity_variance` | Allows the spell to spawn fields. `field_id` describes which field will be spawned, `field_chance` describes the chance as ( 1 / `field_chance`).
`min_field_intensity`, `max_field_intensity` and `field_intensity_increment` modify the field intensity and it's growth (e.g. fd_electricity intensity 1 is "spark", while intensity 10 is "electric cloud").
`field_intensity_variance` allows to randomly increase or decrease the intensity of the spell as a percent (e.g. intensity 10 and variance 0.1 means it can grow or shrink by 10%, or go from 9 to 11). | "field_id": "fd_blood",
"field_chance": 100,
"min_field_intensity": 10,
"max_field_intensity": 10,
"field_intensity_increment": 1,
"field_intensity_variance": 0.1
diff --git a/src/magic.cpp b/src/magic.cpp
index a880e071fa396..63fa757472452 100644
--- a/src/magic.cpp
+++ b/src/magic.cpp
@@ -240,6 +240,9 @@ const int spell_type::max_duration_default = 0;
const int spell_type::min_pierce_default = 0;
const float spell_type::pierce_increment_default = 0.0f;
const int spell_type::max_pierce_default = 0;
+const float spell_type::min_bash_scaling_default = 0.0f;
+const float spell_type::max_bash_scaling_default = 0.0f;
+const float spell_type::bash_scaling_increment_default = 0.0f;
const int spell_type::base_energy_cost_default = 0;
const float spell_type::energy_increment_default = 0.0f;
const trait_id spell_type::spell_class_default = trait_NONE;
@@ -452,6 +455,17 @@ void spell_type::load( const JsonObject &jo, const std::string_view src )
max_pierce = get_dbl_or_var( jo, "max_pierce", false, max_pierce_default );
}
+ if( !was_loaded || jo.has_member( "min_bash_scaling" ) ) {
+ min_bash_scaling = get_dbl_or_var( jo, "min_bash_scaling", false, min_bash_scaling_default );
+ }
+ if( !was_loaded || jo.has_member( "bash_scaling_increment" ) ) {
+ bash_scaling_increment = get_dbl_or_var( jo, "bash_scaling_increment", false,
+ bash_scaling_increment_default );
+ }
+ if( !was_loaded || jo.has_member( "max_bash_scaling" ) ) {
+ max_bash_scaling = get_dbl_or_var( jo, "max_bash_scaling", false, max_bash_scaling_default );
+ }
+
if( !was_loaded || jo.has_member( "base_energy_cost" ) ) {
base_energy_cost = get_dbl_or_var( jo, "base_energy_cost", false,
base_energy_cost_default );
@@ -577,6 +591,12 @@ void spell_type::serialize( JsonOut &json ) const
json.member( "max_pierce", static_cast( max_pierce.min.dbl_val.value() ), max_pierce_default );
json.member( "pierce_increment", static_cast( pierce_increment.min.dbl_val.value() ),
pierce_increment_default );
+ json.member( "min_bash_scaling", static_cast( min_bash_scaling.min.dbl_val.value() ),
+ min_bash_scaling_default );
+ json.member( "max_bash_scaling", static_cast( max_bash_scaling.min.dbl_val.value() ),
+ max_bash_scaling_default );
+ json.member( "bash_scaling_increment",
+ static_cast( bash_scaling_increment.min.dbl_val.value() ), bash_scaling_increment_default );
json.member( "base_energy_cost", static_cast( base_energy_cost.min.dbl_val.value() ),
base_energy_cost_default );
json.member( "final_energy_cost", static_cast( final_energy_cost.min.dbl_val.value() ),
@@ -700,6 +720,25 @@ int spell::field_intensity( const Creature &caster ) const
type->field_intensity_increment.evaluate( d ) ) ) );
}
+double spell::bash_scaling( const Creature &caster ) const
+{
+ dialogue d( get_talker_for( caster ), nullptr );
+ const double leveled_scaling = type->min_bash_scaling.evaluate( d ) + get_effective_level() *
+ type->bash_scaling_increment.evaluate( d );
+ if( has_flag( spell_flag::RANDOM_DAMAGE ) ) {
+ return rng( std::min( leveled_scaling,
+ static_cast( type->max_bash_scaling.evaluate( d ) ) ),
+ std::max( leveled_scaling,
+ static_cast( type->max_bash_scaling.evaluate( d ) ) ) );
+ } else {
+ if( type->max_bash_scaling.evaluate( d ) >= type->min_bash_scaling.evaluate( d ) ) {
+ return std::min( leveled_scaling, static_cast( type->max_bash_scaling.evaluate( d ) ) );
+ } else {
+ return std::max( leveled_scaling, static_cast( type->max_bash_scaling.evaluate( d ) ) );
+ }
+ }
+}
+
int spell::min_leveled_damage( const Creature &caster ) const
{
dialogue d( get_talker_for( caster ), nullptr );
diff --git a/src/magic.h b/src/magic.h
index 7f2e9c929c495..01306e0903331 100644
--- a/src/magic.h
+++ b/src/magic.h
@@ -318,6 +318,10 @@ class spell_type
// max pierce damage
dbl_or_var max_pierce;
+ dbl_or_var min_bash_scaling;
+ dbl_or_var bash_scaling_increment;
+ dbl_or_var max_bash_scaling;
+
// base energy cost of spell
dbl_or_var base_energy_cost;
// increment of energy cost per spell level
@@ -416,6 +420,9 @@ class spell_type
static const int min_pierce_default;
static const float pierce_increment_default;
static const int max_pierce_default;
+ static const float min_bash_scaling_default;
+ static const float max_bash_scaling_default;
+ static const float bash_scaling_increment_default;
static const int base_energy_cost_default;
static const float energy_increment_default;
static const trait_id spell_class_default;
@@ -472,6 +479,8 @@ class spell
// sets the message to be different than the spell_type specifies
void set_message( const translation &msg );
+ double bash_scaling( const Creature &caster ) const;
+
static int exp_for_level( int level );
// how much exp you need for the spell to gain a level
int exp_to_next_level() const;
diff --git a/src/magic_spell_effect.cpp b/src/magic_spell_effect.cpp
index 892d31ba63d2c..2a196510254ee 100644
--- a/src/magic_spell_effect.cpp
+++ b/src/magic_spell_effect.cpp
@@ -583,10 +583,23 @@ static void damage_targets( const spell &sp, Creature &caster,
void spell_effect::attack( const spell &sp, Creature &caster, const tripoint_bub_ms &epicenter )
{
- damage_targets( sp, caster, spell_effect_area( sp, epicenter, caster ) );
+ const std::set area = spell_effect_area( sp, epicenter, caster );
+ damage_targets( sp, caster, area );
if( sp.has_flag( spell_flag::SWAP_POS ) ) {
swap_pos( caster, epicenter );
}
+ const double bash_scaling = sp.bash_scaling( caster );
+ if( bash_scaling > 0 ) {
+ ::map &here = get_map();
+ for( const tripoint_bub_ms &potential_target : area ) {
+ if( !sp.is_valid_target( caster, potential_target ) ) {
+ continue;
+ }
+ // the bash already makes noise, so no need for spell::make_sound()
+ here.bash( potential_target, sp.damage( caster ) * bash_scaling,
+ sp.has_flag( spell_flag::SILENT ) );
+ }
+ }
}
static void magical_polymorph( monster &victim, Creature &caster, const spell &sp )