From 2b2dc8c0e1f61a35bfc7eb067bd1f5ffd7e7471a Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Mon, 5 Aug 2024 12:10:34 +0200 Subject: [PATCH 01/12] Cleaned up rotate --- src/map.h | 1 + src/mapgen.cpp | 84 +++++++++++++++++++++----------------------------- 2 files changed, 36 insertions(+), 49 deletions(-) diff --git a/src/map.h b/src/map.h index d804021569ba5..47eabf4e4d267 100644 --- a/src/map.h +++ b/src/map.h @@ -2197,6 +2197,7 @@ class map // @param turns number of 90 clockwise turns to make // @param setpos_safe if true, being used outside of mapgen and can use setpos to // set NPC positions. if false, cannot use setpos + // Note that this operation actually only works on tinymap and smallmap. void rotate( int turns, bool setpos_safe = false ); // Not protected/private for mapgen.cpp access diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 0c99ae296b5a9..bf0c6930637cd 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -7110,6 +7110,9 @@ computer *map::add_computer( const tripoint &p, const std::string &name, int sec */ void map::rotate( int turns, const bool setpos_safe ) { + if( this->my_MAPSIZE != 2 ) { + debugmsg( "map::rotate called with map too large to be rotated properly. Only the top left overmap will be rotated." ); + } //Handle anything outside the 1-3 range gracefully; rotate(0) is a no-op. turns = turns % 4; @@ -7117,53 +7120,36 @@ void map::rotate( int turns, const bool setpos_safe ) return; } - real_coords rc; const tripoint_abs_sm &abs_sub = get_abs_sub(); - // TODO: fix point types - rc.fromabs( project_to( abs_sub.xy() ).raw() ); + const tripoint_abs_omt abs_omt = project_to( abs_sub ); + + if( abs_sub.x() % 2 != 0 || abs_sub.y() % 2 != 0 ) { + debugmsg( "map::rotate called with map not aligned with overmap boundary. Results will be incorrect at best." ); + } - // TODO: This radius can be smaller - how small? - const int radius = HALF_MAPSIZE + 3; - // uses submap coordinates - const std::vector> npcs = overmap_buffer.get_npcs_near( abs_sub, radius ); + const std::vector> npcs = overmap_buffer.get_npcs_near_omt( abs_omt, 0 ); for( const shared_ptr_fast &i : npcs ) { npc &np = *i; - const tripoint sq = np.get_location().raw(); - real_coords np_rc; - np_rc.fromabs( sq.xy() ); - // Note: We are rotating the entire overmap square (2x2 of submaps) - if( np_rc.om_pos != rc.om_pos || ( sq.z != abs_sub.z() && !zlevels ) ) { + const tripoint_abs_ms sq( np.get_location() ); + + if( sq.z() != abs_sub.z() && !zlevels ) { continue; } - // OK, this is ugly: we remove the NPC from the whole map - // Then we place it back from scratch - // It could be rewritten to utilize the fact that rotation shouldn't cross overmaps + const point_abs_sm npc_sm( np.global_sm_location().xy() ); + const point_bub_ms npc_bub( np.pos_bub().xy() ); + point_bub_ms old( npc_bub.x() % SEEX, npc_bub.y() % SEEY ); - point old( np_rc.sub_pos ); - if( np_rc.om_sub.x % 2 != 0 ) { - old.x += SEEX; + // Note: We are rotating the entire overmap square (2x2 of submaps) + if( npc_sm.x() % 2 != 0 ) { + old.x() += SEEX; } - if( np_rc.om_sub.y % 2 != 0 ) { - old.y += SEEY; + if( npc_sm.y() % 2 != 0 ) { + old.y() += SEEY; } - const point new_pos = old.rotate( turns, { SEEX * 2, SEEY * 2 } ); - if( setpos_safe ) { - const point local_sq = bub_from_abs( sq ).xy().raw(); - // setpos can't be used during mapgen, but spawn_at_precise clips position - // to be between 0-11,0-11 and teleports NPCs when used inside of update_mapgen - // calls - const tripoint new_global_sq = sq - local_sq + new_pos; - np.setpos( get_map().bub_from_abs( new_global_sq ) ); - } else { - // OK, this is ugly: we remove the NPC from the whole map - // Then we place it back from scratch - // It could be rewritten to utilize the fact that rotation shouldn't cross overmaps - shared_ptr_fast npc_ptr = overmap_buffer.remove_npc( np.getID() ); - np.spawn_at_precise( tripoint_abs_ms( getabs( tripoint( new_pos, sq.z ) ) ) ); - overmap_buffer.insert_npc( npc_ptr ); - } + const point_bub_ms new_pos( old.raw().rotate( turns, {SEEX * 2, SEEY * 2} ) ); + np.spawn_at_precise( getglobal( tripoint_bub_ms( new_pos, sq.z() ) ) ); } clear_vehicle_level_caches(); @@ -7235,21 +7221,24 @@ void map::rotate( int turns, const bool setpos_safe ) queued_points.clear(); for( std::pair &queued_point : temp_points ) { //This is all just a copy of the section rotating NPCs above - real_coords np_rc; - np_rc.fromabs( queued_point.second.xy().raw() ); + const point_abs_omt queued_point_omt( project_to( queued_point.second.xy() ) ); + // Note: We are rotating the entire overmap square (2x2 of submaps) - if( np_rc.om_pos != rc.om_pos || ( queued_point.second.z() != abs_sub.z() && !zlevels ) ) { + if( queued_point_omt != abs_omt.xy() || ( queued_point.second.z() != abs_sub.z() && !zlevels ) ) { continue; } - point old( np_rc.sub_pos ); - if( np_rc.om_sub.x % 2 != 0 ) { - old.x += SEEX; + const point_abs_sm queued_point_sm( project_to( queued_point.second.xy() ) ); + const point_bub_ms queued_point_bub( get_map().bub_from_abs( queued_point.second.xy() ) ); + point_bub_ms old( queued_point_bub.x() % SEEX, queued_point_bub.y() % SEEY ); + + if( queued_point_sm.x() % 2 != 0 ) { + old.x() += SEEX; } - if( np_rc.om_sub.y % 2 != 0 ) { - old.y += SEEY; + if( queued_point_sm.y() % 2 != 0 ) { + old.y() += SEEY; } - const point new_pos = old.rotate( turns, { SEEX * 2, SEEY * 2 } ); - queued_points[queued_point.first] = tripoint_abs_ms( getabs( tripoint( new_pos, + const point_bub_ms new_pos( old.raw().rotate( turns, {SEEX * 2, SEEY * 2} ) ); + queued_points[queued_point.first] = tripoint_abs_ms( getabs( tripoint_bub_ms( new_pos, queued_point.second.z() ) ) ); } } @@ -7265,10 +7254,7 @@ void map::mirror( bool mirror_horizontal, bool mirror_vertical ) return; } - real_coords rc; const tripoint_abs_sm &abs_sub = get_abs_sub(); - // TODO: fix point types - rc.fromabs( project_to( abs_sub.xy() ).raw() ); for( int z_level = zlevels ? -OVERMAP_DEPTH : abs_sub.z(); z_level <= ( zlevels ? OVERMAP_HEIGHT : abs_sub.z() ); z_level++ ) { From 7401c86e0256cdd871214b070a9225fa4373d078 Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Mon, 5 Aug 2024 12:41:37 +0200 Subject: [PATCH 02/12] Get rid of unused parameter --- src/map.h | 4 +--- src/mapgen.cpp | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/map.h b/src/map.h index 47eabf4e4d267..6fd4b55003c2f 100644 --- a/src/map.h +++ b/src/map.h @@ -2195,10 +2195,8 @@ class map // Rotates the current map 90*turns degrees clockwise // Useful for houses, shops, etc // @param turns number of 90 clockwise turns to make - // @param setpos_safe if true, being used outside of mapgen and can use setpos to - // set NPC positions. if false, cannot use setpos // Note that this operation actually only works on tinymap and smallmap. - void rotate( int turns, bool setpos_safe = false ); + void rotate( int turns ); // Not protected/private for mapgen.cpp access // Mirrors the current map horizontally and/or vertically (both is technically diff --git a/src/mapgen.cpp b/src/mapgen.cpp index bf0c6930637cd..c700988db38c4 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -7108,7 +7108,7 @@ computer *map::add_computer( const tripoint &p, const std::string &name, int sec * degrees. * @param turns How many 90-degree turns to rotate the map. */ -void map::rotate( int turns, const bool setpos_safe ) +void map::rotate( int turns ) { if( this->my_MAPSIZE != 2 ) { debugmsg( "map::rotate called with map too large to be rotated properly. Only the top left overmap will be rotated." ); @@ -8036,7 +8036,7 @@ class rotation_guard // If the existing map is rotated, we need to rotate it back to the north // orientation before applying our updates. if( rotation != 0 && !md.has_flag( jmapgen_flags::no_underlying_rotate ) ) { - md.m.rotate( rotation, true ); + md.m.rotate( rotation ); } } @@ -8044,7 +8044,7 @@ class rotation_guard // If we rotated the map before applying updates, we now need to rotate // it back to where we found it. if( rotation != 0 && !md.has_flag( jmapgen_flags::no_underlying_rotate ) ) { - md.m.rotate( 4 - rotation, true ); + md.m.rotate( 4 - rotation ); } } private: From fb76226cb2ab705a0108ed1ea3950779c94c6683 Mon Sep 17 00:00:00 2001 From: Sab Pyrope Date: Thu, 15 Aug 2024 15:34:48 +0800 Subject: [PATCH 03/12] artisan weaponsmith --- .../isolated_road_cody_dialogue.json | 35 +++ .../isolated_road_cody_weaponsmith.json | 240 ++++++++++++++++++ 2 files changed, 275 insertions(+) create mode 100644 data/json/npcs/isolated_road/isolated_road_cody_weaponsmith.json diff --git a/data/json/npcs/isolated_road/isolated_road_cody_dialogue.json b/data/json/npcs/isolated_road/isolated_road_cody_dialogue.json index 636853ec973d1..e9df50748980e 100644 --- a/data/json/npcs/isolated_road/isolated_road_cody_dialogue.json +++ b/data/json/npcs/isolated_road/isolated_road_cody_dialogue.json @@ -130,6 +130,31 @@ }, "topic": "TALK_BLACKSMITH_FABRICATE" }, + { + "text": "Could you make me a weapon?", + "condition": { + "and": [ + { "not": { "u_has_var": "dialogue_artisans_gunsmith_mentioned_quest", "value": "yes" } }, + { "not": { "u_has_var": "dialogue_artisans_blacksmith_crafting", "value": "yes" } }, + { "u_has_var": "dialogue_artisans_blacksmith_heard_the_deal", "value": "yes" } + ] + }, + "topic": "TALK_BLACKSMITH_NOT_INTERESTED_FABRICATE" + }, + { + "text": "Could you make me a weapon?", + "condition": { + "and": [ + { "not": { "u_has_var": "dialogue_artisans_blacksmith_crafting", "value": "yes" } }, + { + "//": "this variable means that you have completed quest 1 for Cody and shown Jay", + "u_has_var": "dialogue_artisans_gunsmith_mentioned_quest", + "value": "yes" + } + ] + }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH" + }, { "text": "How is my armor coming?", "condition": { @@ -202,6 +227,16 @@ }, "topic": "TALK_BLACKSMITH_ARMOR_READY" }, + { + "text": "How is my weapon coming?", + "condition": { + "and": [ + { "u_has_var": "dialogue_artisans_blacksmith_crafting", "value": "yes" }, + { "u_has_var": "dialogue_artisans_u_current_project", "value": "weapon" } + ] + }, + "topic": "TALK_BLACKSMITH_WEAPON_READY" + }, { "text": "You mentioned you'd need some special materials to make that nomad armor?", "condition": { diff --git a/data/json/npcs/isolated_road/isolated_road_cody_weaponsmith.json b/data/json/npcs/isolated_road/isolated_road_cody_weaponsmith.json new file mode 100644 index 0000000000000..3e30442d8b759 --- /dev/null +++ b/data/json/npcs/isolated_road/isolated_road_cody_weaponsmith.json @@ -0,0 +1,240 @@ +[ + { + "id": "EOC_blacksmith_weapon_cleanup", + "type": "effect_on_condition", + "effect": [ + { "u_lose_var": "general_artisans_blacksmith_weapon" }, + { "u_lose_var": "general_artisans_blacksmith_weapon_type" }, + { "u_lose_var": "number_artisans_blacksmith_weapon_wait" }, + { "u_lose_var": "number_artisans_blacksmith_weapon_cost" }, + { "u_lose_var": "timer_artisans_u_waiting_on_weapon" } + ] + }, + { + "id": "EOC_blacksmith_weapon_choose_type", + "type": "effect_on_condition", + "condition": { "expects_vars": [ "name", "cost", "wait" ] }, + "effect": [ + { "run_eocs": [ "EOC_blacksmith_weapon_cleanup" ] }, + { + "set_string_var": { "context_val": "name" }, + "target_var": { "u_val": "general_artisans_blacksmith_weapon_type" } + }, + { "math": [ "u_number_artisans_blacksmith_weapon_cost", "=", "_cost" ] }, + { "math": [ "u_number_artisans_blacksmith_weapon_wait", "=", "_wait" ] } + ] + }, + { + "id": "TALK_BLACKSMITH_WEAPONSMITH", + "//": "this is all the dialogue related to working on weapon with Cody", + "type": "talk_topic", + "dynamic_line": { + "compare_string": [ "", { "u_val": "general_artisans_blacksmith_weapon" } ], + "yes": { + "gendered_line": "Sure. After what you've done for me, I'll forge you the finest work of art. The price and waiting time depend on the size of the weapon in question, but it will take me a fair amount of money to buy the quality steel I need from the scavengers, and even forging a short blade will take a few days.\n\nI can also temper your weapon, but that will cost an additional 50 merch and take an additional 2 days, but I assure you, it's worth it.", + "relevant_genders": [ "u" ] + }, + "no": "Do you still want to order your > or would you like to choose something else?" + }, + "responses": [ + { "text": "Forget it.", "topic": "TALK_BLACKSMITH_SERVICES" }, + { + "text": "Yes, I want to order it.", + "condition": { "not": { "compare_string": [ "", { "u_val": "general_artisans_blacksmith_weapon" } ] } }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_PAYMENT" + }, + { + "text": "[200 merch, 3 days] I need a mace.", + "effect": { "run_eoc_with": "EOC_blacksmith_weapon_choose_type", "variables": { "name": "mace", "cost": "200", "wait": "3" } }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_STEEL" + }, + { + "text": "[200 merch, 3 days] I need a steelshod quarterstaff.", + "effect": { + "run_eoc_with": "EOC_blacksmith_weapon_choose_type", + "variables": { "name": "steel_staff", "cost": "200", "wait": "3" } + }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_STEEL" + }, + { + "text": "[250 merch, 4 days] I need a battle axe.", + "effect": { + "run_eoc_with": "EOC_blacksmith_weapon_choose_type", + "variables": { "name": "battleaxe", "cost": "250", "wait": "4" } + }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_STEEL" + }, + { + "text": "[250 merch, 4 days] I need a longsword.", + "effect": { + "run_eoc_with": "EOC_blacksmith_weapon_choose_type", + "variables": { "name": "longsword", "cost": "250", "wait": "4" } + }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_STEEL" + }, + { + "text": "[250 merch, 4 days] I need a nodachi.", + "effect": { "run_eoc_with": "EOC_blacksmith_weapon_choose_type", "variables": { "name": "nodachi", "cost": "250", "wait": "4" } }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_STEEL" + }, + { + "text": "[250 merch, 4 days] I need a zweihander.", + "effect": { + "run_eoc_with": "EOC_blacksmith_weapon_choose_type", + "variables": { "name": "zweihander", "cost": "250", "wait": "4" } + }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_STEEL" + }, + { + "text": "[200 merch, 3 days] I need an arming sword.", + "effect": { + "run_eoc_with": "EOC_blacksmith_weapon_choose_type", + "variables": { "name": "arming_sword", "cost": "200", "wait": "3" } + }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_STEEL" + }, + { + "text": "[200 merch, 3 days] I need a broadsword.", + "effect": { + "run_eoc_with": "EOC_blacksmith_weapon_choose_type", + "variables": { "name": "broadsword", "cost": "200", "wait": "3" } + }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_STEEL" + }, + { + "text": "[200 merch, 3 days] I need a cavalry saber.", + "effect": { + "run_eoc_with": "EOC_blacksmith_weapon_choose_type", + "variables": { "name": "cavalry_sabre", "cost": "200", "wait": "3" } + }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_STEEL" + }, + { + "text": "[200 merch, 3 days] I need a cutlass.", + "effect": { "run_eoc_with": "EOC_blacksmith_weapon_choose_type", "variables": { "name": "cutlass", "cost": "200", "wait": "3" } }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_STEEL" + }, + { + "text": "[200 merch, 3 days] I need a katana.", + "effect": { "run_eoc_with": "EOC_blacksmith_weapon_choose_type", "variables": { "name": "katana", "cost": "200", "wait": "3" } }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_STEEL" + }, + { + "text": "[170 merch, 3 days] I need a wakizashi.", + "effect": { + "run_eoc_with": "EOC_blacksmith_weapon_choose_type", + "variables": { "name": "wakizashi", "cost": "170", "wait": "3" } + }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_STEEL" + }, + { + "text": "[150 merch, 2 days] I need a kukri.", + "effect": { "run_eoc_with": "EOC_blacksmith_weapon_choose_type", "variables": { "name": "kukri", "cost": "150", "wait": "2" } }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_STEEL" + }, + { + "text": "[250 merch, 4 days] I need an estoc.", + "effect": { "run_eoc_with": "EOC_blacksmith_weapon_choose_type", "variables": { "name": "estoc", "cost": "250", "wait": "4" } }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_STEEL" + }, + { + "text": "[200 merch, 3 days] I need a rapier.", + "effect": { "run_eoc_with": "EOC_blacksmith_weapon_choose_type", "variables": { "name": "rapier", "cost": "200", "wait": "3" } }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_STEEL" + }, + { + "text": "[70 merch, 2 days] I need a trench knife.", + "effect": { + "run_eoc_with": "EOC_blacksmith_weapon_choose_type", + "variables": { "name": "knife_trench", "cost": "70", "wait": "2" } + }, + "topic": "TALK_BLACKSMITH_WEAPONSMITH_STEEL" + } + ] + }, + { + "id": "TALK_BLACKSMITH_WEAPONSMITH_STEEL", + "//": "this is all the dialogue related to working on weapon with Cody", + "type": "talk_topic", + "dynamic_line": "Okay. What about the steel grade? Tempering will make your weapon much more durable and a little sharper.", + "responses": [ + { + "text": "No, high carbon steel is fine.", + "effect": [ + { + "set_string_var": "hc_", + "target_var": { "u_val": "general_artisans_blacksmith_weapon" }, + "parse_tags": true + } + ], + "topic": "TALK_BLACKSMITH_WEAPONSMITH_PAYMENT" + }, + { + "text": "[+50 merch, +2 days] Yes, tempered steel would be excellent.", + "effect": [ + { + "set_string_var": "qt_", + "target_var": { "u_val": "general_artisans_blacksmith_weapon" }, + "parse_tags": true + }, + { "math": [ "u_number_artisans_blacksmith_weapon_cost", "+=", "50" ] }, + { "math": [ "u_number_artisans_blacksmith_weapon_wait", "+=", "2" ] } + ], + "topic": "TALK_BLACKSMITH_WEAPONSMITH_PAYMENT" + }, + { "text": "Forget it.", "topic": "TALK_BLACKSMITH_SERVICES" } + ] + }, + { + "id": "TALK_BLACKSMITH_WEAPONSMITH_PAYMENT", + "//": "this is all the dialogue related to working on weapon with Cody", + "type": "talk_topic", + "dynamic_line": "Great, so I can make your > for merch and in days. Deal?", + "responses": [ + { + "text": "[ merch] Deal. See you in days.", + "condition": { "u_has_items": { "item": "FMCNote", "count": { "u_val": "number_artisans_blacksmith_weapon_cost" } } }, + "switch": true, + "effect": [ + { "u_sell_item": "FMCNote", "count": { "u_val": "number_artisans_blacksmith_weapon_cost" } }, + { "u_add_var": "dialogue_artisans_u_current_project", "value": "weapon" }, + { "u_add_var": "dialogue_artisans_blacksmith_crafting", "value": "yes" }, + { "math": [ "u_timer_artisans_u_waiting_on_weapon", "=", "time('now')" ] } + ], + "topic": "TALK_DONE" + }, + { + "text": "Um… wait, I don't have that kind of money right now.", + "switch": true, + "topic": "TALK_BLACKSMITH_SERVICES" + }, + { "text": "Forget it.", "topic": "TALK_BLACKSMITH_SERVICES" } + ] + }, + { + "id": "TALK_BLACKSMITH_WEAPON_READY", + "type": "talk_topic", + "dynamic_line": { + "math": [ "time_since(u_timer_artisans_u_waiting_on_weapon, 'unit':'days')", ">=", "u_number_artisans_blacksmith_weapon_wait" ], + "yes": "It's all done! Sorry for the long wait; hopefully it's worth it.", + "no": "Still working on it." + }, + "responses": [ + { + "text": "Thanks.", + "condition": { + "math": [ "time_since(u_timer_artisans_u_waiting_on_weapon, 'unit':'days')", ">=", "u_number_artisans_blacksmith_weapon_wait" ] + }, + "switch": true, + "effect": [ + { "u_add_var": "dialogue_artisans_blacksmith_crafting", "value": "no" }, + { "u_add_var": "dialogue_artisans_u_current_project", "value": "none" }, + { "u_spawn_item": { "u_val": "general_artisans_blacksmith_weapon" } }, + { "run_eocs": [ "EOC_blacksmith_weapon_cleanup" ] } + ], + "topic": "TALK_BLACKSMITH_SERVICES" + }, + { "text": "See you when it's done.", "switch": true, "topic": "TALK_DONE" } + ] + } +] From e05bffd4a5d149499e7a7de311dfba6d5c7244dc Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Fri, 30 Aug 2024 13:00:06 -0700 Subject: [PATCH 04/12] Doc outlining how batteries are represented in the game --- doc/batteries_and_electricity.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 doc/batteries_and_electricity.md diff --git a/doc/batteries_and_electricity.md b/doc/batteries_and_electricity.md new file mode 100644 index 0000000000000..7d2a80ec9dd69 --- /dev/null +++ b/doc/batteries_and_electricity.md @@ -0,0 +1,15 @@ +The way that batteries, power storage, and electricity use are handled is a pile of compromises, so this document outlines the decisions about these topics and some of the rationales for them. + +## Voltage, Current, Capacity +The short of it is, we are not handling voltage and current explicitly, only capacity. +As we are not designing systems but rather representing them, it's reasonable to assume that a particular class of battery is generally fit for purpose. +For example, we assume that battery cells for handheld devices are able to activate those handheld devices, even though in reality some devices require higher current than average batteries will provide. Once you scale up to e.g. electric vehicle battery packs, we assume that a car-scale battery pack is fit for purpose, even though in reality moving a battery from one electric vehicle to another would likely be an extremely difficult endeavor. +There is some possiblility of making different batteries or other power sources not fit for purpose for certain tasks, but this would be realized via some labelling like "high-draw power source" rather than attempting to model voltage and current limits explicitly. + +## Battery representation +Matching batteries to a particular electrical device can be a pain, but is it a fun or interesting kind of pain? I assert not, and as such we are not handling a wide variety of different battery types and sizes that have to be matched to the device, but abstracting battery packs to a near-minimal representative set of size classes to cover all our devices. +Likewise, many electronic devices accept some number of standard sized battery cells, but this isn't a particularly interesting detail, so instead we are abstracting battery compartments to holding a single battery cell of an appropriate capacity and not handling multiple cells per device. +In order to make reasoning about cells a bit easier, the capacities and dimensions of cells correlate with standard battery form factors when appropriate and they have comments indicating this relationship, but the ids, names and descriptions of the items do not because indicating that a particular battery is similar to for exampe an AA cell would be more confusing than informative since they are not used in the same way. Using a small LED flashlight as an example, it is likely to have a battery compartment that accepts three AAA battery cells, but in-game we would not use 3 AAA cells but rather a single cell about the size of a C or D battery. If we called that battery a D cell, it's quite likely that players would ignore it because IRL D cells are relatively niche, while in DDA they would be extremely common. + +## Matching batteries to devices +When adding a battery powered device to the game, the most important aspect to get right for representativeness is overall runtime. Get an estimate for how long the device would be able to operate on standard batteries and try to set the power consumption and battery type it accepts to roughly match that runtime. This is a highly subjective process because device manufacturers are highly incentivised to be misleading when they make claims about battery life, so be skeptical of manufacturer claims, but if they aren't too out there or if it's not that impactful, don't worry about it too much. Generally higher draw and shorter the battery life of a device is an indication to be more careful about accuracy, if it's very low draw and/or the IRL device legitimately has much greater capacity than it needs, tolerances are very loose, but if the device chronically runs out of power quicky IRL it becomes more important to not under- or over- estimate how long it will be able to operate. \ No newline at end of file From bd7d7090cc4e88d3375f20367d0266f8542e8ed9 Mon Sep 17 00:00:00 2001 From: akrieger Date: Mon, 2 Sep 2024 16:52:26 -0700 Subject: [PATCH 05/12] Fix point hash to be well distributed. --- src/map.cpp | 14 +++++++------- src/map.h | 4 ++-- src/point.h | 41 +++++++++++++++++++++++++++++------------ 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/map.cpp b/src/map.cpp index 3042a73a93858..93f7c94b1c839 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -7778,17 +7778,17 @@ bool map::sees( const tripoint_bub_ms &F, const tripoint_bub_ms &T, const int ra // TODO: Change this to a hash function on the map implementation. This will also allow us to // account for the complete lack of entropy in the top 16 bits. -int64_t map::sees_cache_key( const tripoint_bub_ms &from, const tripoint_bub_ms &to ) const +point map::sees_cache_key( const tripoint_bub_ms &from, const tripoint_bub_ms &to ) const { // Canonicalize the order of the tripoints so the cache is reflexive. const tripoint_bub_ms &min = from < to ? from : to; const tripoint_bub_ms &max = !( from < to ) ? from : to; // A little gross, just pack the values into an integer. - return - static_cast( min.x() ) << 50 | static_cast( min.y() ) << 40 | - ( static_cast( min.z() ) + OVERMAP_DEPTH ) << 30 | max.x() << 20 | max.y() << 10 | - ( max.z() + OVERMAP_DEPTH ); + return point( + min.x() << 20 | min.y() << 10 | ( min.z() + OVERMAP_DEPTH ), + max.x() << 20 | max.y() << 10 | ( max.z() + OVERMAP_DEPTH ) + ); } /** @@ -7812,7 +7812,7 @@ bool map::sees( const tripoint_bub_ms &F, const tripoint_bub_ms &T, const int ra bresenham_slope = 0; return false; // Out of range! } - const int64_t key = sees_cache_key( F, T ); + const point key = sees_cache_key( F, T ); if( allow_cached ) { char cached = skew_cache.get( key, -1 ); if( cached != -1 ) { @@ -11116,7 +11116,7 @@ void map::invalidate_max_populated_zlev( int zlev ) bool map::has_potential_los( const tripoint_bub_ms &from, const tripoint_bub_ms &to ) const { - const int64_t key = sees_cache_key( from, to ); + const point key = sees_cache_key( from, to ); char cached = skew_vision_cache.get( key, -1 ); if( cached != -1 ) { return cached > 0; diff --git a/src/map.h b/src/map.h index 4ede732195a15..0c90a8a9e8523 100644 --- a/src/map.h +++ b/src/map.h @@ -702,7 +702,7 @@ class map bool with_fields = true ) const; bool sees( const tripoint_bub_ms &F, const tripoint_bub_ms &T, int range, int &bresenham_slope, bool with_fields = true, bool allow_cached = true ) const; - int64_t sees_cache_key( const tripoint_bub_ms &from, const tripoint_bub_ms &to ) const; + point sees_cache_key( const tripoint_bub_ms &from, const tripoint_bub_ms &to ) const; public: /** * Returns coverage of target in relation to the observer. Target is loc2, observer is loc1. @@ -2602,7 +2602,7 @@ class map /** * Cache of coordinate pairs recently checked for visibility. */ - using lru_cache_t = lru_cache; + using lru_cache_t = lru_cache; mutable lru_cache_t skew_vision_cache; mutable lru_cache_t skew_vision_wo_fields_cache; diff --git a/src/point.h b/src/point.h index 3047978be41d7..fd95f65349720 100644 --- a/src/point.h +++ b/src/point.h @@ -303,11 +303,20 @@ namespace std template <> struct hash { std::size_t operator()( const point &k ) const noexcept { - constexpr uint64_t a = 2862933555777941757; - size_t result = k.y; - result *= a; - result += k.x; - return result; + // We cast k.y to uint32_t because otherwise when promoting to uint64_t for binary `or` it + // will sign extend and turn the upper 32 bits into all 1s. + uint64_t x = static_cast( k.x ) << 32 | static_cast( k.y ); + + // Found through https://nullprogram.com/blog/2018/07/31/ + // Public domain source from https://xoshiro.di.unimi.it/splitmix64.c + x ^= x >> 30; + x *= 0xbf58476d1ce4e5b9U; + x ^= x >> 27; + x *= 0x94d049bb133111ebU; + x ^= x >> 31; + return x; + + return x; } }; } // namespace std @@ -319,13 +328,21 @@ namespace std template <> struct hash { std::size_t operator()( const tripoint &k ) const noexcept { - constexpr uint64_t a = 2862933555777941757; - size_t result = k.z; - result *= a; - result += k.y; - result *= a; - result += k.x; - return result; + // We cast k.y to uint32_t because otherwise when promoting to uint64_t for binary `or` it + // will sign extend and turn the upper 32 bits into all 1s. + uint64_t x = static_cast( k.x ) << 32 | static_cast( k.y ); + + // Found through https://nullprogram.com/blog/2018/07/31/ + // Public domain source from https://xoshiro.di.unimi.it/splitmix64.c + x ^= x >> 30; + x *= 0xbf58476d1ce4e5b9U; + x ^= x >> 27; + + // Sprinkle in z now. + x ^= static_cast( k.z ); + x *= 0x94d049bb133111ebU; + x ^= x >> 31; + return x; } }; } // namespace std From b4577e22527f047336ffe50ff46fd2aecb9dd380 Mon Sep 17 00:00:00 2001 From: DukePaulAtreid3s <146854355+DukePaulAtreid3s@users.noreply.github.com> Date: Fri, 6 Sep 2024 08:56:58 -0400 Subject: [PATCH 06/12] Why are you like this? --- data/json/item_actions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/item_actions.json b/data/json/item_actions.json index fbfddf39ce881..b770779d8f273 100644 --- a/data/json/item_actions.json +++ b/data/json/item_actions.json @@ -737,7 +737,7 @@ { "type": "item_action", "id": "RADIO_ON", - "name": { "str": "scan" } + "name": { "str": "Scan" } }, { "type": "item_action", From 38ad76f47ec631e153bac9ccf7c79f0d9ac0590d Mon Sep 17 00:00:00 2001 From: Standing-Storm <120433252+Standing-Storm@users.noreply.github.com> Date: Fri, 6 Sep 2024 14:31:52 -0500 Subject: [PATCH 07/12] [MoM] Add two snippets (#76219) * Initial commit * Update data/mods/MindOverMatter/snippets/snippets_new.json Co-authored-by: Maleclypse <54345792+Maleclypse@users.noreply.github.com> * A couple other small changes --------- Co-authored-by: Maleclypse <54345792+Maleclypse@users.noreply.github.com> --- .../MindOverMatter/snippets/snippets_new.json | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/data/mods/MindOverMatter/snippets/snippets_new.json b/data/mods/MindOverMatter/snippets/snippets_new.json index c52cc11a9356d..789685f560f39 100644 --- a/data/mods/MindOverMatter/snippets/snippets_new.json +++ b/data/mods/MindOverMatter/snippets/snippets_new.json @@ -323,27 +323,39 @@ { "name": "On Time Travel", "id": "lab_file_teleportation_01", + "weight": 800, "text": "Let's start with the obvious. Teleportation is moving faster than light, by definition. Even though our most powerful mathematicians can currently only teleport a few grams a few meters distant, we've used slow-motion photography and confirmed that while the transit is not instantaneous, it's still faster than c. So, as the saying goes, relativity, causality, faster than light travel, pick two, right? Which are we going to pick?\n\nWell, as much as it pains me as a physicist to say it, relativity, at least as it relates in this case. Now we have a third domain alongside quantum mechanics and general relativity: netherum mathematics. While I hesitate to speculate on something that we have collected so little data on, it is possible that the Netherum provides its own reference frame coterminous with our own (or multiple) realities. If we built our satellites with matrix technology, would they still need to account for time dilation? Would relativity override netherum mathematics in that case?\n\nBut to return to the title: there is no evidence time travel is possible despite repeated attempts. Perhaps if we had a LOST RAIN mathematician capable of moving interstellar distances we could ask them to come back before they left. Barring that, I'm afraid asking LOST RAIN to retroactively avert any disasters is not on the table." }, { "name": "COBALT RAIN progress report", "id": "lab_file_teleportation_02", + "weight": 500, "text": "Alright, so should I even be working on this? The world is ending, we're on lockdown, and I'm pretty sure some of my coworkers have lost their minds. I should be looking for ways to get out of here, right? But hell, I've always buried myself in my work in a crisis and this sure is one of those. So my report is that ever since we detected the spread of XE037, COBALT RAIN has been running at…well, it's a perpetual motion machine so I can't exactly talk about \"increased efficiency\" but it's been putting out even more power than it was a month ago. On the order of 3x more. Maybe all that nonsense about the fabric of space expanding or whatever was right? I regret to inform you that it's still occasionally popping out monsters, though fortunately the only thing I had to deal with so far has been those blobs and I set up an isolation chamber for COBALT RAIN to run in. It's keeping the lights on down here, so there's that. If I can just fix that one flaw, we'll see set. Too bad my assistant is out trying to figure out how to jump floor to floor so they don't have to use the stairs anymore." }, { "name": "testing report I4-9469", "id": "lab_file_teleportation_03", + "weight": 1000, "text": "Testing began with an area two meters square, marked on the floor by electrical tape. A robot set to travel at a constant speed of 0.1 m/s, verified before the experiment began, was set on one side of the testing area before LOST RAIN mathematician D85 used his abilities on the area. The robot traversed the space in 16 seconds, verified by both its internal measuring software and external measurements. We repeated the experiment with a request to extend the relative distance, causing the robot to take 25 seconds to traverse the space. It is currently unclear whether the disparity in relative distance change is a property of LOST RAIN itself or of D85's abilities.\n\nThe only difficulty was caused when Dr. Caldwell crossed through the marked space before D85 had ceased maintaining the distortion and almost immediately collapsed. She was rushed to the infirmary but in the end was discharged after tests showed that she had fainted but suffered no lasting damage. Dr. Caldwell explained she had experienced severe vertigo on entering the area, possibly caused by a defect in proprioception caused by actual distance being different than perceived distance. I have submitted a proposal to further test this characteristic of LOST RAIN--see attached." }, { "name": "testing report B4-2567", "id": "lab_file_teleportation_04", + "weight": 1000, "text": "Attempt 1: Move pencil at least 400 cm: Successful\nAttempt 2: Move pencil at least 2 m: Failed\nAttempt 3: Move pencil inside sealed, clear plastic bag to outside the bag: Successful\nAttempt 4: Move pencil inside sealed, opaque plastic bag outside the bag: Failed\nAttempt 5: Move eraser without moving the rest of the pencil: Failed\nAttempt 6: Rotate pencil during transit of at least 400 cm so that eraser previously facing the door is now facing away from the door: Successful\nAttempt 7: Move pencil 400 cm into pencil sharpener: Successful\nAttempt 8: Move pencil at least 400 cm into bucket of water: Successful\nAttempt 9: Move pencil at least 400 cm into block of ice: Failed\nAttempt 10: Move stationary pencil 400 cm so that it arrives at destination with upward velocity: Failed\nAttempt 11: Preserve velocity of falling pencil after moving it at least 400 cm: Successful\nAttempt 12: Move pencil gripped firmly in hand at least 400 cm: Successful" }, { "name": "It's alive! IT'S ALIVE!", "id": "lab_file_teleportation_05", + "weight": 700, "text": "Like we won't be for much longer.\n\nNews outside is a nightmare. I saw some phone video of a giant monster destroying LA before the net went down. There's no way I'll be able to report this to Dr. Liu, but I finally made a breakthrough. Or maybe I should say, a breakthrough was made, because I sure as hell didn't do anything to cause it. I went to go test QN283 today and it just worked. I didn't change anything, I didn't make any adjustments, I just turned on the remote and the payload vanished and reappeared near the beacon just like it was supposed to. Is this because of the end of the world? I can hear gunfire and shouting in the distance and there's nowhere to run because we're been on lockdown for weeks but I invent functional teleportation, one of the greatest discoveries in human history? Great.\n\nIf I only had gotten C78 to sneak a beacon outside before lockdown. If she can get out of here with her powers, maybe I can still escape." + }, + { + "name": "Incident report: 2945883 (again)", + "id": "lab_file_teleportation_06", + "weight": 500, + "//": "XE754 here are the Hounds of Tindalos", + "text": "At 1238 yesterday during COBALT RAIN testing, a malfunction occurred, leading to a power surge in the matrix crystal housing. While Dr. Simmons immediately engaged the shutdown sequence and prevented any damage to the prototype, smoke began filling the room after her actions. I hit the alarm button but security did not respond before the appearance of an entity since designated XE754. XE754 immediately attacked Dr. Simmons and Dr. Rodriguez and, though security did arrive within the ideal 1 minute response time, XE754 seemed to be nearly immune to small-arms fire. Dr. Simmons suffered serious injuries during the attack and when XE754 retreated it appeared to take her with it. The smoke vanished soon afterward and the COBALT RAIN prototype was successfully returned to an inactive state.\n\nFinally, I must protest at the treatment I have received over my accounting of the incident. This is the third report I have submitted and I have not changed my story in any way. I was there. I know what I saw. I do not understand why I am being put through this or why sole responsibility is being assigned to me when I was not in charge of the project. I especially do not understand why Dr. Rodriguez has not been subject to the same process nor why I have not been permitted to speak to him. I worked with him and Julia on this project for six months! I refuse to be treated this way.\nArthur Mitchell\nResearcher, COBALT RAIN" } ] }, @@ -522,6 +534,12 @@ "id": "lab_file_phavian_memo_07", "weight": 1000, "text": "No mathematician should be subject to more than ten hours of testing in a two-day period. Any period of more than four hours of continuous testing must include a half-hour meal break. Mathematicians are entitled to the same work-week and schedule as researchers are, including days off. Mathematicians will be informed of the purpose and subject of any experiment they take part in and may register a complaint with HR if they object to their participation. Note that this does not absolve each mathematician from fulfilling the duties of their employment. Mathematicians must wear their identifying badges at all times when on-site and present them for inspection at the request of any member of security.\n\nOur mathematicians are not cases, they are not subjects, and they are certainly not \"guinea pigs\" or \"lab rats.\" They are valuable partners in our exploration of dimensional metaphysics, irreplaceable personnel, and should be treated as such. Researchers found violating these guidelines will be sanctioned, up to and including termination of employment." + }, + { + "name": "re: re: Incident report: 2945883 (again!!!)", + "id": "lab_file_phavian_memo_08", + "weight": 500, + "text": "Dr. Mitchell,\nPer our last email, Dr. Enrique Rodriguez passed away in a car accident almost two years ago, shortly after being assigned to XEDRA as a portal research specialist, and he never had the opportunity to work with XEDRA-23. As you can see from the employee database, there has never been a Dr. Julia Simmons employed by either XEDRA-23 or any other XEDRA division.\n\nIn addition, the XEDRA handbook requires that all employees use their current title in their signature at all times. Please update your signature to comply with this policy.\nAlicia Sanders\nSenior Talent Coodinator" } ] }, From 2003ed0d8e3630df914f2147e00bb1e5cb16a719 Mon Sep 17 00:00:00 2001 From: Standing-Storm <120433252+Standing-Storm@users.noreply.github.com> Date: Fri, 6 Sep 2024 14:57:50 -0500 Subject: [PATCH 08/12] [Magiclysm] Move bulk of spellcasting proficiency processing to dedicated EoCs and out of spell JSON (Druid/Earthshaper edition) (#76197) * Add RESTORATION and TRANSFORMATION categories * Update magic.h * Add Restoration and Transformation proficiencies * Add Restoration and Transformation proficiencies * Add transformation and Restoration proficiency improvement EoCs * Add transformation proficiency modifier * Add restoration and transformation proficiency setup * Add Restoration/Transformation spell categories * Add Restoration/Transformation categories * Update data/mods/Magiclysm/Spells/biomancer.json Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update data/mods/Magiclysm/eoc_spell_casting_proficiencies.json Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update data/mods/Magiclysm/eoc_spell_casting_proficiencies.json Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Druid spells * Add Earthshaper spells * Fix restoration adjustments --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- data/mods/Magiclysm/Spells/animist.json | 12 +- data/mods/Magiclysm/Spells/biomancer.json | 55 +- data/mods/Magiclysm/Spells/classless.json | 42 ++ data/mods/Magiclysm/Spells/druid.json | 489 +++++++++--------- data/mods/Magiclysm/Spells/earthshaper.json | 370 +++++++------ .../eoc_spell_casting_proficiencies.json | 120 +++++ data/mods/Magiclysm/jmath.json | 24 + data/mods/Magiclysm/magic_balance.md | 6 + data/mods/Magiclysm/proficiencies.json | 72 +++ src/magic.cpp | 8 + src/magic.h | 2 + 11 files changed, 735 insertions(+), 465 deletions(-) diff --git a/data/mods/Magiclysm/Spells/animist.json b/data/mods/Magiclysm/Spells/animist.json index 6c39055f698b3..c8b75a04042ce 100644 --- a/data/mods/Magiclysm/Spells/animist.json +++ b/data/mods/Magiclysm/Spells/animist.json @@ -65,8 +65,8 @@ "base_casting_time": 50000, "base_energy_cost": 5000, "energy_increment": 500.0, - "flags": [ "CHANNELING_SPELL", "SOMATIC", "VERBAL", "PAIN_NORESIST" ], - "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], + "flags": [ "RESTORATION_SPELL", "SOMATIC", "VERBAL", "PAIN_NORESIST" ], + "extra_effects": [ { "id": "eoc_restoration_setup", "hit_self": true } ], "final_energy_cost": 10000 }, { @@ -524,7 +524,7 @@ "name": "Convert", "description": "Kill an allied creature, converting its life energy into a compact rune that you can use afterwards.", "valid_targets": [ "ally" ], - "flags": [ "CHANNELING_SPELL", "CONCENTRATE", "SOMATIC", "SILENT", "PERCENTAGE_DAMAGE" ], + "flags": [ "TRANSFORMATION_SPELL", "CONCENTRATE", "SOMATIC", "SILENT", "PERCENTAGE_DAMAGE" ], "effect": "attack", "shape": "blast", "message": "", @@ -540,7 +540,7 @@ "final_casting_time": 1000, "casting_time_increment": -200, "energy_source": "MANA", - "extra_effects": [ { "id": "create_rune_animist", "hit_self": true }, { "id": "eoc_channeling_setup", "hit_self": true } ] + "extra_effects": [ { "id": "create_rune_animist", "hit_self": true }, { "id": "eoc_transformation_setup", "hit_self": true } ] }, { "id": "soulrend", @@ -982,7 +982,7 @@ "type": "SPELL", "name": { "str": "Spirit-Walking" }, "description": "Transform your body to pure spirit, making you invisible and intangible. You can move incredibly quickly while the spell is in effect and can pass by enemies unseen, but you will be unable to affect the physical world or cast spells.", - "flags": [ "ENHANCEMENT_SPELL", "SOMATIC", "CONCENTRATE", "VERBAL" ], + "flags": [ "TRANSFORMATION_SPELL", "SOMATIC", "CONCENTRATE", "VERBAL" ], "spell_class": "ANIMIST", "effect": "effect_on_condition", "effect_str": "EOC_ANIMIST_SPIRIT_WALKING", @@ -999,7 +999,7 @@ "base_energy_cost": 1200, "final_energy_cost": 850, "energy_increment": -17.5, - "extra_effects": [ { "id": "eoc_enhancement_setup", "hit_self": true } ] + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ] }, { "type": "effect_on_condition", diff --git a/data/mods/Magiclysm/Spells/biomancer.json b/data/mods/Magiclysm/Spells/biomancer.json index a89b66a6a98b1..2a20f501c5160 100644 --- a/data/mods/Magiclysm/Spells/biomancer.json +++ b/data/mods/Magiclysm/Spells/biomancer.json @@ -16,8 +16,8 @@ "shape": "blast", "base_casting_time": 300, "base_energy_cost": 800, - "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], - "flags": [ "CHANNELING_SPELL", "SOMATIC", "VERBAL", "NO_PROJECTILE" ], + "extra_effects": [ { "id": "eoc_restoration_setup", "hit_self": true } ], + "flags": [ "RESTORATION_SPELL", "SOMATIC", "VERBAL", "NO_PROJECTILE" ], "spell_class": "BIOMANCER", "difficulty": 2, "energy_source": "MANA" @@ -32,9 +32,10 @@ "shape": "blast", "base_casting_time": 100, "base_energy_cost": 800, - "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], + "//": "This is transformation because it moves wounds around, it does not actually heal anything.", + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ], "energy_source": "MANA", - "flags": [ "CHANNELING_SPELL", "SOMATIC", "NO_LEGS", "CONCENTRATE" ], + "flags": [ "TRANSFORMATION_SPELL", "SOMATIC", "NO_LEGS", "CONCENTRATE" ], "spell_class": "BIOMANCER", "difficulty": 4, "max_level": 1 @@ -55,10 +56,10 @@ "min_duration": 24000, "max_duration": 360000, "duration_increment": 24000, - "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ], "difficulty": 6, "max_level": 15, - "flags": [ "CONJURATION_SPELL", "SOMATIC", "LOUD" ], + "flags": [ "TRANSFORMATION_SPELL", "SOMATIC", "LOUD" ], "spell_class": "BIOMANCER", "learn_spells": { "vicious_tentacle_plus": 15 }, "energy_source": "MANA" @@ -83,10 +84,10 @@ "min_duration": 360000, "max_duration": 2160000, "duration_increment": 72000, - "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ], "difficulty": 7, "max_level": 25, - "flags": [ "CONJURATION_SPELL", "LOUD", "NO_FAIL" ], + "flags": [ "TRANSFORMATION_SPELL", "LOUD", "NO_FAIL" ], "spell_class": "BIOMANCER", "energy_source": "MANA" }, @@ -102,7 +103,7 @@ "base_casting_time": 100, "casting_time_increment": -2.5, "final_casting_time": 50, - "extra_effects": [ { "id": "eoc_enhancement_setup", "hit_self": true } ], + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ], "base_energy_cost": 250, "energy_increment": -5.0, "final_energy_cost": 150, @@ -110,7 +111,7 @@ "spell_class": "BIOMANCER", "difficulty": 6, "max_level": 20, - "flags": [ "ENHANCEMENT_SPELL", "SOMATIC", "LOUD" ], + "flags": [ "TRANSFORMATION_SPELL", "SOMATIC", "LOUD" ], "//": "duration is in moves", "min_duration": 6000, "max_duration": 60000, @@ -160,10 +161,10 @@ "min_duration": 360000, "max_duration": 9000000, "duration_increment": 360000, - "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ], "difficulty": 4, "max_level": 20, - "flags": [ "CONJURATION_SPELL", "NO_HANDS", "NO_LEGS", "SOMATIC" ], + "flags": [ "TRANSFORMATION_SPELL", "NO_HANDS", "NO_LEGS", "SOMATIC" ], "spell_class": "BIOMANCER", "energy_source": "MANA" }, @@ -446,7 +447,7 @@ "description": "Grow webbing on your hands and feet, making quick swimming a breeze.", "valid_targets": [ "self" ], "spell_class": "BIOMANCER", - "flags": [ "ENHANCEMENT_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC" ], + "flags": [ "TRANSFORMATION_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC" ], "effect": "attack", "effect_str": "effect_biomancer_swim_speed", "shape": "blast", @@ -455,7 +456,7 @@ "min_duration": 120000, "max_duration": 360000, "duration_increment": 24000, - "extra_effects": [ { "id": "eoc_enhancement_setup", "hit_self": true } ], + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ], "energy_source": "MANA", "base_energy_cost": 200, "base_casting_time": 1000 @@ -467,7 +468,7 @@ "description": "Grow to enormous size. Your clothing and equipment will not grow with you.", "valid_targets": [ "self" ], "spell_class": "BIOMANCER", - "flags": [ "ENHANCEMENT_SPELL", "VERBAL", "SOMATIC" ], + "flags": [ "TRANSFORMATION_SPELL", "VERBAL", "SOMATIC" ], "effect": "effect_on_condition", "effect_str": "EOC_GIANT_GROWTH_MUTATION", "shape": "blast", @@ -478,7 +479,7 @@ "duration_increment": 4000, "energy_source": "MANA", "base_energy_cost": 500, - "extra_effects": [ { "id": "eoc_enhancement_setup", "hit_self": true } ], + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ], "base_casting_time": 100 }, { @@ -501,7 +502,7 @@ { "u_add_trait": "BIO_GIANT_GROWTH" }, { "queue_eocs": "EOC_GIANT_GROWTH_MUTATION_REMOVE", - "time_in_future": { "math": [ "(( u_spell_level('biomancer_giant_growth') * 40 ) + 300 ) * ( enhancement_proficiency_modifier() )" ] } + "time_in_future": { "math": [ "(( u_spell_level('biomancer_giant_growth') * 40 ) + 300 ) * ( transformation_proficiency_modifier() )" ] } } ], "false_effect": [ { "u_message": "You are already enormous--the spell cannot make you any larger!" } ] @@ -575,7 +576,7 @@ "description": "Grow a pair of lashing tentacles from your shoulders. While not as long as the Vicious Tentacle, they will strike anyone in melee with you. You cannot wear rigid armor that covers the shoulders with them.", "valid_targets": [ "self" ], "spell_class": "BIOMANCER", - "flags": [ "CONJURATION_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC" ], + "flags": [ "TRANSFORMATION_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC" ], "effect": "effect_on_condition", "effect_str": "EOC_LASHING_TENTACLES_MUTATION", "shape": "blast", @@ -584,7 +585,7 @@ "min_duration": 7000, "max_duration": 30000, "duration_increment": 1533, - "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ], "energy_source": "MANA", "base_energy_cost": 400, "base_casting_time": 500 @@ -598,7 +599,9 @@ { "u_add_trait": "BIO_LASHING_TENTACLES" }, { "queue_eocs": "EOC_LASHING_TENTACLES_MUTATION_REMOVE", - "time_in_future": { "math": [ "(( u_spell_level('biomancer_lashing_tentacles') * 15 ) + 70 ) * (summoning_proficiency_modifier() )" ] } + "time_in_future": { + "math": [ "(( u_spell_level('biomancer_lashing_tentacles') * 15 ) + 70 ) * (transformation_proficiency_modifier() )" ] + } } ], "false_effect": [ { "u_message": "You already have a pair of lashing tentacles!" } ] @@ -618,7 +621,7 @@ "description": "Cure any minor illnesses you might be suffering from. This is one of the few biomantic cure spells that is castable on other people.", "valid_targets": [ "self", "ally" ], "spell_class": "BIOMANCER", - "flags": [ "ENHANCEMENT_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC" ], + "flags": [ "RESTORATION_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC" ], "effect": "attack", "effect_str": "effect_biomancer_cure_disease_minor", "shape": "blast", @@ -630,7 +633,7 @@ "max_range": 1, "energy_source": "MANA", "base_energy_cost": 500, - "extra_effects": [ { "id": "eoc_enhancement_setup", "hit_self": true } ], + "extra_effects": [ { "id": "eoc_restoration_setup", "hit_self": true } ], "base_casting_time": 90000, "final_casting_time": 30000, "casting_time_increment": -6000 @@ -642,7 +645,7 @@ "description": "Possibly the most powerful of the biomantic healing spells, this causes your flesh to literally knit itself together before your eyes.", "valid_targets": [ "self" ], "spell_class": "BIOMANCER", - "flags": [ "ENHANCEMENT_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC" ], + "flags": [ "RESTORATION_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC" ], "effect": "attack", "effect_str": "effect_biomancer_hyper_regeneration", "shape": "blast", @@ -652,7 +655,7 @@ "max_duration": 13000, "duration_increment": 500, "energy_source": "MANA", - "extra_effects": [ { "id": "eoc_enhancement_setup", "hit_self": true } ], + "extra_effects": [ { "id": "eoc_restoration_setup", "hit_self": true } ], "base_energy_cost": 900, "base_casting_time": 150 }, @@ -714,7 +717,7 @@ "description": "Change each of your fingers into a myriad of tiny bone knives, allowing you to cut with surgical precision… or slice your enemies to ribbons.", "valid_targets": [ "self" ], "spell_class": "BIOMANCER", - "flags": [ "CONJURATION_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC" ], + "flags": [ "TRANSFORMATION_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC" ], "difficulty": 5, "max_level": 20, "effect": "spawn_item", @@ -724,7 +727,7 @@ "max_duration": 360000, "duration_increment": 24000, "energy_source": "MANA", - "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ], "base_energy_cost": 300, "base_casting_time": 500 }, diff --git a/data/mods/Magiclysm/Spells/classless.json b/data/mods/Magiclysm/Spells/classless.json index 943416f7ab9d7..a11d29aaaf55b 100644 --- a/data/mods/Magiclysm/Spells/classless.json +++ b/data/mods/Magiclysm/Spells/classless.json @@ -702,5 +702,47 @@ "final_energy_cost": 0, "base_casting_time": 0, "final_casting_time": 0 + }, + { + "id": "eoc_restoration_setup", + "type": "SPELL", + "name": "Set Up Proficiency: Restoration", + "description": "Sets up proficiency gain. This is a bug if you have it.", + "valid_targets": [ "self" ], + "spell_class": "NONE", + "flags": [ "NO_LEGS" ], + "difficulty": 0, + "min_damage": 1, + "max_damage": 1, + "duration_increment": 1, + "effect": "effect_on_condition", + "effect_str": "EOC_SPELLCASTING_RESTORATION_PROFICIENCY_ADD", + "shape": "blast", + "energy_source": "NONE", + "base_energy_cost": 0, + "final_energy_cost": 0, + "base_casting_time": 0, + "final_casting_time": 0 + }, + { + "id": "eoc_transformation_setup", + "type": "SPELL", + "name": "Set Up Proficiency: Transformation", + "description": "Sets up proficiency gain. This is a bug if you have it.", + "valid_targets": [ "self" ], + "spell_class": "NONE", + "flags": [ "NO_LEGS" ], + "difficulty": 0, + "min_damage": 1, + "max_damage": 1, + "duration_increment": 1, + "effect": "effect_on_condition", + "effect_str": "EOC_SPELLCASTING_TRANSFORMATION_PROFICIENCY_ADD", + "shape": "blast", + "energy_source": "NONE", + "base_energy_cost": 0, + "final_energy_cost": 0, + "base_casting_time": 0, + "final_casting_time": 0 } ] diff --git a/data/mods/Magiclysm/Spells/druid.json b/data/mods/Magiclysm/Spells/druid.json index e82e14eee5ca3..479a44714bece 100644 --- a/data/mods/Magiclysm/Spells/druid.json +++ b/data/mods/Magiclysm/Spells/druid.json @@ -5,7 +5,7 @@ "name": "Vegetative Grasp", "description": "This spell causes roots and vines to burst forth from the ground and grab your foes, slowing them and doing a small amount of damage as they dig in.", "valid_targets": [ "hostile", "ground" ], - "flags": [ "LOUD", "SOMATIC", "VERBAL", "NO_LEGS", "NO_PROJECTILE" ], + "flags": [ "EVOCATION_SPELL", "LOUD", "SOMATIC", "VERBAL", "NO_LEGS", "NO_PROJECTILE" ], "effect": "attack", "effect_str": "entangled", "shape": "blast", @@ -15,18 +15,18 @@ "energy_source": "MANA", "difficulty": 2, "max_level": 20, - "min_damage": { "math": [ "evocation_proficiency_bonus_calculate(1, 0.2)" ] }, - "max_damage": { "math": [ "evocation_proficiency_bonus_calculate(10, 0.2)" ] }, - "damage_increment": { "math": [ "evocation_proficiency_bonus_calculate(0.5, 0.06)" ] }, + "min_damage": 1, + "max_damage": 10, + "damage_increment": 0.5, "min_aoe": 4, "max_aoe": 15, "aoe_increment": 1.0, "min_range": 3, "max_range": 10, "range_increment": 1.0, - "min_duration": { "math": [ "evocation_proficiency_bonus_calculate(1000, 5)" ] }, - "max_duration": { "math": [ "evocation_proficiency_bonus_calculate(10000, 5)" ] }, - "duration_increment": { "math": [ "evocation_proficiency_bonus_calculate(500, 0.06)" ] }, + "min_duration": 1000, + "max_duration": 10000, + "duration_increment": 500, "min_pierce": 1, "max_pierce": 5, "pierce_increment": 0.25, @@ -39,7 +39,7 @@ "name": "Root Strike", "description": "This spell causes roots to spear out of the ground in a cone and stab into your foes, impaling them.", "valid_targets": [ "hostile", "ground" ], - "flags": [ "LOUD", "SOMATIC", "VERBAL", "NO_LEGS" ], + "flags": [ "EVOCATION_SPELL", "LOUD", "SOMATIC", "VERBAL", "NO_LEGS" ], "effect": "attack", "effect_str": "root_impale", "shape": "cone", @@ -49,9 +49,9 @@ "energy_source": "MANA", "difficulty": 4, "max_level": 20, - "min_damage": { "math": [ "evocation_proficiency_bonus_calculate(15, 0.5)" ] }, - "max_damage": { "math": [ "evocation_proficiency_bonus_calculate(60, 0.5)" ] }, - "damage_increment": { "math": [ "evocation_proficiency_bonus_calculate(2.5, 0.06)" ] }, + "min_damage": 15, + "max_damage": 60, + "damage_increment": 2.5, "min_aoe": 25, "max_aoe": 45, "aoe_increment": 1.0, @@ -61,9 +61,9 @@ "min_dot": 1, "max_dot": 2, "dot_increment": 0.1, - "min_duration": { "math": [ "evocation_proficiency_bonus_calculate(1000, 5)" ] }, - "max_duration": { "math": [ "evocation_proficiency_bonus_calculate(10000, 5)" ] }, - "duration_increment": { "math": [ "evocation_proficiency_bonus_calculate(500, 0.06)" ] }, + "min_duration": 1000, + "max_duration": 10000, + "duration_increment": 500, "min_pierce": 10, "max_pierce": 20, "pierce_increment": 0.5, @@ -76,7 +76,7 @@ "name": "Wooden Shaft", "description": "This spell creates a projectile of hardwood that shoots forth from the caster's hand at high speed to stab into an enemy.", "valid_targets": [ "hostile" ], - "flags": [ "LOUD", "SOMATIC", "VERBAL", "NO_LEGS" ], + "flags": [ "EVOCATION_SPELL", "LOUD", "SOMATIC", "VERBAL", "NO_LEGS" ], "effect": "attack", "shape": "blast", "spell_class": "DRUID", @@ -85,9 +85,9 @@ "energy_source": "MANA", "difficulty": 1, "max_level": 20, - "min_damage": { "math": [ "evocation_proficiency_bonus_calculate(1, 0.2)" ] }, - "max_damage": { "math": [ "evocation_proficiency_bonus_calculate(25, 0.2)" ] }, - "damage_increment": { "math": [ "evocation_proficiency_bonus_calculate(1.5, 0.0625)" ] }, + "min_damage": 1, + "max_damage": 25, + "damage_increment": 1.5, "min_range": 5, "max_range": 15, "range_increment": 0.75, @@ -103,7 +103,7 @@ "name": "Nature's Bow", "description": "This spell conjures a magical wooden recurve bow, as well as a quiver and a set of arrows to go with it.", "valid_targets": [ "none" ], - "flags": [ "CONCENTRATE", "SOMATIC", "VERBAL", "NO_LEGS" ], + "flags": [ "CONJURATION_SPELL", "CONCENTRATE", "SOMATIC", "VERBAL", "NO_LEGS" ], "extra_effects": [ { "id": "druid_naturequiver1" }, { "id": "druid_naturearrows1" }, { "id": "eoc_summon_setup", "hit_self": true } ], "min_damage": 1, "max_damage": 1, @@ -111,10 +111,10 @@ "effect_str": "druid_recurve", "shape": "blast", "base_casting_time": 200, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(250, 3)" ] }, - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(24000, 300)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(360000, 300)" ] }, - "duration_increment": { "math": [ "summoning_proficiency_bonus_calculate(24000, 0.04)" ] }, + "base_energy_cost": 250, + "min_duration": 24000, + "max_duration": 360000, + "duration_increment": 24000, "difficulty": 5, "max_level": 15, "spell_class": "DRUID", @@ -127,14 +127,14 @@ "name": "Nature's Quiver", "description": "This spell conjures a magical quiver as part of the nature's bow spell. It's a bug if you have it directly.", "valid_targets": [ "none" ], - "flags": [ "SILENT" ], + "flags": [ "CONJURATION_SPELL", "SILENT" ], "min_damage": 1, "max_damage": 1, "effect": "spawn_item", "effect_str": "druid_quiver", "shape": "blast", - "min_duration": { "math": [ "( (u_spell_level('druid_naturebow1') * 24000) + 24000)" ] }, - "max_duration": { "math": [ "( (u_spell_level('druid_naturebow1') * 24000) + 24000)" ] } + "min_duration": { "math": [ "( (u_spell_level('druid_naturebow1') * 24000) + 24000) * (summoning_proficiency_modifier())" ] }, + "max_duration": { "math": [ "( (u_spell_level('druid_naturebow1') * 24000) + 24000) * (summoning_proficiency_modifier())" ] } }, { "id": "druid_naturearrows1", @@ -142,14 +142,14 @@ "name": "Nature's Arrows", "description": "This spell conjures magical arrows as part of the nature's bow spell. It's a bug if you have it directly.", "valid_targets": [ "none" ], - "flags": [ "SILENT" ], - "min_damage": { "math": [ "( (u_spell_level('druid_naturebow1') * 3) + 15)" ] }, - "max_damage": { "math": [ "( (u_spell_level('druid_naturebow1') * 3) + 15)" ] }, + "flags": [ "CONJURATION_SPELL", "SILENT" ], + "min_damage": { "math": [ "( (u_spell_level('druid_naturebow1') * 3) + 15) * (summoning_proficiency_modifier())" ] }, + "max_damage": { "math": [ "( (u_spell_level('druid_naturebow1') * 3) + 15) * (summoning_proficiency_modifier())" ] }, "effect": "spawn_item", "effect_str": "druid_naturearrows1", "shape": "blast", - "min_duration": { "math": [ "( (u_spell_level('druid_naturebow1') * 24000) + 24000)" ] }, - "max_duration": { "math": [ "( (u_spell_level('druid_naturebow1') * 24000) + 24000)" ] } + "min_duration": { "math": [ "( (u_spell_level('druid_naturebow1') * 24000) + 24000) * (summoning_proficiency_modifier())" ] }, + "max_duration": { "math": [ "( (u_spell_level('druid_naturebow1') * 24000) + 24000) * (summoning_proficiency_modifier())" ] } }, { "id": "druid_naturebow1_plus", @@ -157,7 +157,7 @@ "name": "Improved Nature's Bow", "description": "This spell conjures a magical wooden recurve bow, as well as a quiver and a set of arrows to go with it. Now you know this spell like the back of your hand, and have started to design your own version.", "valid_targets": [ "none" ], - "flags": [ "SOMATIC", "VERBAL", "NO_LEGS", "NO_FAIL" ], + "flags": [ "CONJURATION_SPELL", "SOMATIC", "VERBAL", "NO_LEGS", "NO_FAIL" ], "extra_effects": [ { "id": "druid_naturequiver1_plus" }, { "id": "druid_naturearrows1_plus" }, @@ -171,12 +171,12 @@ "base_casting_time": 200, "final_casting_time": 100, "casting_time_increment": -4, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(250, 1)" ] }, - "final_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(100, 1)" ] }, - "energy_increment": { "math": [ "summoning_proficiency_negate_calculate(-6, 0.04)" ] }, - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(360000, 3000)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(2160000, 3000)" ] }, - "duration_increment": { "math": [ "summoning_proficiency_bonus_calculate(72000, 0.04)" ] }, + "base_energy_cost": 250, + "final_energy_cost": 100, + "energy_increment": -6, + "min_duration": 360000, + "max_duration": 2160000, + "duration_increment": 72000, "difficulty": 7, "max_level": 25, "spell_class": "DRUID", @@ -188,14 +188,14 @@ "name": "Nature's Quiver", "description": "This spell conjures a magical quiver as part of the nature's bow spell. It's a bug if you have it directly.", "valid_targets": [ "none" ], - "flags": [ "SILENT" ], + "flags": [ "CONJURATION_SPELL", "SILENT" ], "min_damage": 1, "max_damage": 1, "effect": "spawn_item", "effect_str": "druid_quiver_plus", "shape": "blast", - "min_duration": { "math": [ "( (u_spell_level('druid_naturebow1_plus') * 72000) + 360000)" ] }, - "max_duration": { "math": [ "( (u_spell_level('druid_naturebow1_plus') * 72000) + 360000)" ] } + "min_duration": { "math": [ "( (u_spell_level('druid_naturebow1_plus') * 72000) + 360000) * (summoning_proficiency_modifier())" ] }, + "max_duration": { "math": [ "( (u_spell_level('druid_naturebow1_plus') * 72000) + 360000) * (summoning_proficiency_modifier())" ] } }, { "id": "druid_naturearrows1_plus", @@ -203,14 +203,14 @@ "name": "Nature's Arrows", "description": "This spell conjures magical arrows as part of the nature's bow spell. It's a bug if you have it directly.", "valid_targets": [ "none" ], - "flags": [ "SILENT" ], - "min_damage": { "math": [ "( (u_spell_level('druid_naturebow1_plus') * 4) + 30)" ] }, - "max_damage": { "math": [ "( (u_spell_level('druid_naturebow1_plus') * 4) + 30)" ] }, + "flags": [ "CONJURATION_SPELL", "SILENT" ], + "min_damage": { "math": [ "( (u_spell_level('druid_naturebow1_plus') * 4) + 30) * (summoning_proficiency_modifier())" ] }, + "max_damage": { "math": [ "( (u_spell_level('druid_naturebow1_plus') * 4) + 30) * (summoning_proficiency_modifier())" ] }, "effect": "spawn_item", "effect_str": "druid_naturearrows1", "shape": "blast", - "min_duration": { "math": [ "( (u_spell_level('druid_naturebow1_plus') * 72000) + 360000)" ] }, - "max_duration": { "math": [ "( (u_spell_level('druid_naturebow1_plus') * 72000) + 360000)" ] } + "min_duration": { "math": [ "( (u_spell_level('druid_naturebow1_plus') * 72000) + 360000) * (summoning_proficiency_modifier())" ] }, + "max_duration": { "math": [ "( (u_spell_level('druid_naturebow1_plus') * 72000) + 360000) * (summoning_proficiency_modifier())" ] } }, { "id": "recover_sleepiness", @@ -218,21 +218,21 @@ "name": "Nature's Trance", "description": "Your connection to living things allows you to go into a magical trance. This allows you to recover from fatigue quickly in exchange for mana.", "valid_targets": [ "self" ], - "flags": [ "CONCENTRATE", "SILENT", "NO_HANDS" ], + "flags": [ "RESTORATION_SPELL", "CONCENTRATE", "SILENT", "NO_HANDS" ], "spell_class": "DRUID", "energy_source": "MANA", "effect": "recover_energy", "effect_str": "SLEEPINESS", "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_bonus_calculate(10000, 100)" ] }, + "base_casting_time": 10000, "min_damage": 50, "damage_increment": 10.0, "max_damage": 300, "max_level": 25, - "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(500, 5)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(25, 0.04)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1125, 5)" ] }, + "extra_effects": [ { "id": "eoc_restoration_setup", "hit_self": true } ], + "base_energy_cost": 500, + "energy_increment": 25, + "final_energy_cost": 1125, "difficulty": 4 }, { @@ -241,7 +241,7 @@ "name": { "str": "Bag of Cats" }, "description": "Are you the crazy cat lady?", "valid_targets": [ "ground" ], - "flags": [ "LOUD", "SOMATIC", "SPAWN_GROUP", "NO_CORPSE_QUIET" ], + "flags": [ "CONJURATION_SPELL", "LOUD", "SOMATIC", "SPAWN_GROUP", "NO_CORPSE_QUIET" ], "min_damage": 1, "max_damage": 12, "damage_increment": 1.0, @@ -255,11 +255,11 @@ "energy_source": "MANA", "max_level": 25, "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(6000, 30)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(60000, 30)" ] }, - "duration_increment": { "math": [ "summoning_proficiency_bonus_calculate(1000, 0.018)" ] }, + "min_duration": 6000, + "max_duration": 60000, + "duration_increment": 1000, "difficulty": 1, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(265, 3)" ] }, + "base_energy_cost": 265, "shape": "blast", "effect": "summon", "effect_str": "GROUP_STRAY_CATS" @@ -280,14 +280,14 @@ "energy_source": "MANA", "max_level": 25, "difficulty": 10, - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(6000, 60)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(30000, 60)" ] }, - "duration_increment": { "math": [ "summoning_proficiency_bonus_calculate(1000, 0.042)" ] }, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(675, 3)" ] }, + "min_duration": 6000, + "max_duration": 30000, + "duration_increment": 1000, + "base_energy_cost": 675, "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], "final_energy_cost": 475, "energy_increment": -5.0, - "flags": [ "HOSTILE_50", "CONCENTRATE", "SOMATIC", "VERBAL", "NO_LEGS", "NO_CORPSE_QUIET" ], + "flags": [ "CONJURATION_SPELL", "HOSTILE_50", "CONCENTRATE", "SOMATIC", "VERBAL", "NO_LEGS", "NO_CORPSE_QUIET" ], "shape": "blast", "effect": "summon", "effect_str": "mon_bear" @@ -307,10 +307,10 @@ "max_level": 20, "difficulty": 4, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(175, 1)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(550, 2)" ] }, + "base_energy_cost": 175, + "base_casting_time": 550, "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], - "flags": [ "CONCENTRATE", "VERBAL", "SOMATIC", "NO_LEGS", "NO_HANDS", "NO_PROJECTILE" ] + "flags": [ "CHANNELING_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC", "NO_LEGS", "NO_HANDS", "NO_PROJECTILE" ] }, { "id": "create_rune_druid", @@ -333,7 +333,7 @@ "spell_class": "DRUID", "energy_source": "MANA", "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], - "flags": [ "PERMANENT", "NO_LEGS", "CONCENTRATE" ] + "flags": [ "CHANNELING_SPELL", "PERMANENT", "NO_LEGS", "CONCENTRATE" ] }, { "id": "purify_seed", @@ -349,16 +349,16 @@ "base_casting_time": 30000, "final_casting_time": 6000, "casting_time_increment": -1200.0, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(1000, 3)" ] }, - "final_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(1000, 3)" ] }, - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(6000, 30)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(6000, 30)" ] }, + "base_energy_cost": 1000, + "final_energy_cost": 1000, + "min_duration": 6000, + "max_duration": 6000, "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], "difficulty": 6, "max_level": 20, "spell_class": "DRUID", "energy_source": "MANA", - "flags": [ "NO_LEGS", "CONCENTRATE" ] + "flags": [ "CONJURATION_SPELL", "NO_LEGS", "CONCENTRATE" ] }, { "id": "druidic_regrowth", @@ -369,13 +369,13 @@ "effect": "ter_transform", "effect_str": "druidic_renewal", "shape": "blast", - "flags": [ "CONCENTRATE", "VERBAL", "SOMATIC", "NO_LEGS", "NO_HANDS", "NO_PROJECTILE" ], + "flags": [ "RESTORATION_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC", "NO_LEGS", "NO_HANDS", "NO_PROJECTILE" ], "spell_class": "DRUID", "energy_source": "HP", "difficulty": 6, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(600, 4)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(25, 0.5)" ] }, - "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], + "base_casting_time": 600, + "base_energy_cost": 25, + "extra_effects": [ { "id": "eoc_restoration_setup", "hit_self": true } ], "max_level": 20, "min_aoe": 1, "max_aoe": 5, @@ -392,15 +392,15 @@ "valid_targets": [ "ally" ], "effect": "attack", "shape": "blast", - "flags": [ "CONCENTRATE", "VERBAL", "SOMATIC", "NO_LEGS", "NO_HANDS", "NO_PROJECTILE" ], + "flags": [ "RESTORATION_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC", "NO_LEGS", "NO_HANDS", "NO_PROJECTILE" ], "spell_class": "DRUID", "energy_source": "HP", "difficulty": 5, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(400, 3.5)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(35, 0.5)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(20, 0.5)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-1.5, 0.1)" ] }, - "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], + "base_casting_time": 400, + "base_energy_cost": 35, + "final_energy_cost": 20, + "energy_increment": -1.5, + "extra_effects": [ { "id": "eoc_restoration_setup", "hit_self": true } ], "max_level": 10, "min_damage": -4, "max_damage": -12, @@ -418,14 +418,14 @@ "name": "Tornskin", "description": "This spell, which resembles Thornskin through the sap & needles covering the page, seemed to involve thorns and bleeding wounds. The marred words may have altered the function.", "valid_targets": [ "hostile", "ground", "ally", "self" ], - "flags": [ "SOMATIC" ], + "flags": [ "EVOCATION_SPELL", "SOMATIC" ], "effect": "attack", "effect_str": "tornskin_pain", "shape": "blast", "affected_body_parts": [ "head", "torso", "mouth", "eyes", "arm_l", "arm_r", "hand_r", "hand_l", "leg_l", "foot_l", "foot_r" ], - "min_dot": { "math": [ "evocation_proficiency_bonus_calculate(1, 0.1)" ] }, - "max_dot": { "math": [ "evocation_proficiency_bonus_calculate(4, 0.1)" ] }, - "dot_increment": { "math": [ "evocation_proficiency_bonus_calculate(0.3, 0.1)" ] }, + "min_dot": 1, + "max_dot": 4, + "dot_increment": 0.3, "extra_effects": [ { "id": "eoc_evocation_setup", "hit_self": true } ], "spell_class": "DRUID", "base_casting_time": 300, @@ -442,9 +442,9 @@ "min_range": 1, "max_range": 2, "range_increment": 0.1, - "min_duration": { "math": [ "evocation_proficiency_bonus_calculate(200, 1)" ] }, - "max_duration": { "math": [ "evocation_proficiency_bonus_calculate(600, 1)" ] }, - "duration_increment": { "math": [ "evocation_proficiency_bonus_calculate(40, 0.1)" ] }, + "min_duration": 200, + "max_duration": 600, + "duration_increment": 40, "min_pierce": 0, "max_pierce": 3, "pierce_increment": 0.3, @@ -459,20 +459,20 @@ "effect": "spawn_item", "effect_str": "aura_feral", "shape": "blast", - "flags": [ "SOMATIC", "VERBAL" ], + "flags": [ "TRANSFORMATION_SPELL", "SOMATIC", "VERBAL" ], "components": "spell_components_feralform", "spell_class": "DRUID", "energy_source": "MANA", "difficulty": 4, - "base_casting_time": { "math": [ "enhancement_proficiency_negate_calculate(400, 2)" ] }, + "base_casting_time": 400, "base_energy_cost": 200, "max_level": 15, "min_damage": 1, "max_damage": 1, - "min_duration": { "math": [ "enhancement_proficiency_bonus_calculate(24000, 2240)" ] }, - "max_duration": { "math": [ "enhancement_proficiency_bonus_calculate(360000, 2240)" ] }, - "duration_increment": { "math": [ "enhancement_proficiency_bonus_calculate(24000, 0.07)" ] }, - "extra_effects": [ { "id": "eoc_enhancement_setup", "hit_self": true } ], + "min_duration": 24000, + "max_duration": 360000, + "duration_increment": 24000, + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ], "learn_spells": { "druid_feralform_plus": 15 } }, { @@ -484,24 +484,24 @@ "effect": "spawn_item", "effect_str": "aura_feral_plus", "shape": "blast", - "flags": [ "SOMATIC", "NO_FAIL" ], + "flags": [ "TRANSFORMATION_SPELL", "SOMATIC", "NO_FAIL" ], "components": "spell_components_feralform", "spell_class": "DRUID", "energy_source": "MANA", "difficulty": 6, - "base_casting_time": { "math": [ "enhancement_proficiency_negate_calculate(400, 1)" ] }, - "final_casting_time": { "math": [ "enhancement_proficiency_negate_calculate(100, 1)" ] }, - "casting_time_increment": { "math": [ "enhancement_proficiency_negate_calculate(-12, 0.04)" ] }, + "base_casting_time": 400, + "final_casting_time": 100, + "casting_time_increment": -12, "base_energy_cost": 200, "final_energy_cost": 100, "energy_increment": -4, "max_level": 25, "min_damage": 1, "max_damage": 1, - "min_duration": { "math": [ "enhancement_proficiency_bonus_calculate(360000, 12000)" ] }, - "max_duration": { "math": [ "enhancement_proficiency_bonus_calculate(2160000, 12000)" ] }, - "duration_increment": { "math": [ "enhancement_proficiency_bonus_calculate(72000, 0.04)" ] }, - "extra_effects": [ { "id": "eoc_enhancement_setup", "hit_self": true } ] + "min_duration": 360000, + "max_duration": 2160000, + "duration_increment": 72000, + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ] }, { "id": "summon_wolf_druid", @@ -522,12 +522,12 @@ "energy_source": "MANA", "max_level": 30, "difficulty": 6, - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(36000, 300)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(1080000, 300)" ] }, - "duration_increment": { "math": [ "summoning_proficiency_bonus_calculate(36000, 0.04)" ] }, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(400, 2)" ] }, + "min_duration": 36000, + "max_duration": 1080000, + "duration_increment": 36000, + "base_energy_cost": 400, "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], - "flags": [ "SOMATIC", "VERBAL", "NO_LEGS", "NO_CORPSE_QUIET" ], + "flags": [ "CONJURATION_SPELL", "SOMATIC", "VERBAL", "NO_LEGS", "NO_CORPSE_QUIET" ], "shape": "blast", "effect": "summon", "effect_str": "mon_wolf" @@ -541,14 +541,14 @@ "effect": "effect_on_condition", "effect_str": "EOC_NATURE_COMMUNE", "shape": "blast", - "flags": [ "CONCENTRATE", "SOMATIC", "VERBAL", "NO_LEGS", "NO_HANDS" ], + "flags": [ "CHANNELING_SPELL", "CONCENTRATE", "SOMATIC", "VERBAL", "NO_LEGS", "NO_HANDS" ], "energy_source": "MANA", "spell_class": "DRUID", "difficulty": 4, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(12000, 100)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(250, 4)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(400, 4)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(10, 0.07)" ] }, + "base_casting_time": 12000, + "base_energy_cost": 250, + "final_energy_cost": 400, + "energy_increment": 10, "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], "max_level": 20, "min_duration": 30000, @@ -574,15 +574,17 @@ "effect": [ { "u_add_effect": "natures_commune", - "duration": { "math": [ "( 300 + (u_spell_level('druid_natures_commune') * 165)) " ] } + "duration": { "math": [ "( 300 + (u_spell_level('druid_natures_commune') * 165)) * ( channeling_proficiency_modifier() )" ] } }, { "u_lose_morale": "morale_forest_unity" }, { "u_add_morale": "morale_forest_unity", - "bonus": { "math": [ "5 + (u_spell_level('druid_natures_commune') * 3)" ] }, + "bonus": { "math": [ "5 + (u_spell_level('druid_natures_commune') * 3) * ( channeling_proficiency_modifier() )" ] }, "max_bonus": 50, - "duration": { "math": [ "( 300 + (u_spell_level('druid_natures_commune') * 165) )" ] }, - "decay_start": { "math": [ "(( 300 + (u_spell_level('druid_natures_commune') * 165) ) / 2)" ] } + "duration": { "math": [ "( 300 + (u_spell_level('druid_natures_commune') * 165) ) * ( channeling_proficiency_modifier() )" ] }, + "decay_start": { + "math": [ "(( 300 + (u_spell_level('druid_natures_commune') * 165) ) / 2) * ( channeling_proficiency_modifier() )" ] + } } ], "false_effect": [ { "u_message": "You must be surrounded by nature to commune with nature", "type": "bad" } ] @@ -597,10 +599,10 @@ "effect": "spawn_item", "effect_str": "druid_fertilizer", "shape": "blast", - "base_casting_time": { "math": [ "summoning_proficiency_negate_calculate(360000, 300)" ] }, - "final_casting_time": { "math": [ "summoning_proficiency_negate_calculate(90000, 300)" ] }, - "casting_time_increment": { "math": [ "summoning_proficiency_negate_calculate(-15000, 0.055)" ] }, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(5, 0.1)" ] }, + "base_casting_time": 360000, + "final_casting_time": 90000, + "casting_time_increment": -15000, + "base_energy_cost": 5, "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], "energy_source": "HP", "difficulty": 4, @@ -609,7 +611,7 @@ "max_damage": 80, "damage_increment": 4, "//": "The spell can only be permanent without being at maximum level because of how items with charges work", - "flags": [ "SOMATIC", "NO_LEGS", "PERMANENT" ] + "flags": [ "CONJURATION_SPELL", "SOMATIC", "NO_LEGS", "PERMANENT" ] }, { "id": "cause_rot", @@ -624,18 +626,18 @@ ], "shape": "blast", "valid_targets": [ "hostile", "ground" ], - "flags": [ "SOMATIC", "NO_PROJECTILE", "CONCENTRATE", "VERBAL", "IGNORE_WALLS" ], + "flags": [ "CHANNELING_SPELL", "SOMATIC", "NO_PROJECTILE", "CONCENTRATE", "VERBAL", "IGNORE_WALLS" ], "max_level": 25, "spell_class": "DRUID", "energy_source": "MANA", "difficulty": 8, "damage_type": "necrotic", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(10000, 10)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(500, 10)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-380, 0.04)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1000, 5)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(400, 5)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-24, 0.04)" ] }, + "base_casting_time": 10000, + "final_casting_time": 500, + "casting_time_increment": -380, + "base_energy_cost": 1000, + "final_energy_cost": 400, + "energy_increment": -24, "min_aoe": 5, "max_aoe": 50, "aoe_increment": 1.8, @@ -657,7 +659,7 @@ "effect_str": "ter_druid_cause_rot_terrain", "shape": "blast", "valid_targets": [ "hostile", "ground" ], - "flags": [ "SOMATIC", "NO_PROJECTILE", "CONCENTRATE", "VERBAL", "IGNORE_WALLS" ], + "flags": [ "CHANNELING_SPELL", "SOMATIC", "NO_PROJECTILE", "CONCENTRATE", "VERBAL", "IGNORE_WALLS" ], "max_level": 25, "spell_class": "DRUID", "min_aoe": 5, @@ -672,7 +674,7 @@ "effect": "bash", "shape": "blast", "valid_targets": [ "hostile", "ground" ], - "flags": [ "SOMATIC", "NO_PROJECTILE", "CONCENTRATE", "VERBAL", "IGNORE_WALLS" ], + "flags": [ "CHANNELING_SPELL", "SOMATIC", "NO_PROJECTILE", "CONCENTRATE", "VERBAL", "IGNORE_WALLS" ], "max_level": 25, "spell_class": "DRUID", "min_aoe": 5, @@ -691,19 +693,19 @@ "effect": "effect_on_condition", "effect_str": "EOC_DRUID_RESTORATION", "shape": "blast", - "flags": [ "CONCENTRATE", "SOMATIC", "VERBAL", "NO_LEGS" ], + "flags": [ "RESTORATION_SPELL", "CONCENTRATE", "SOMATIC", "VERBAL", "NO_LEGS" ], "energy_source": "MANA", "spell_class": "DRUID", "difficulty": 8, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(12000, 15)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(3000, 15)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-360, 0.04)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800, 5)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(500, 5)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-12, 0.04)" ] }, - "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], + "base_casting_time": 12000, + "final_casting_time": 3000, + "casting_time_increment": -360, + "base_energy_cost": 800, + "final_energy_cost": 500, + "energy_increment": -12, + "extra_effects": [ { "id": "eoc_restoration_setup", "hit_self": true } ], "max_level": 25, - "//": "each 3000 (30 second) heal 1 hp. 5 hp on level 0 (2.5m), 30 hp on level 25 (15 m)", + "//": "each 3000 (30 second) heal 1 hp. 5 hp on level 0 (2.5m), 30 hp on level 25 (15 m), ignoring proficiency modifiers", "min_duration": 15000, "max_duration": 90000, "duration_increment": 3000 @@ -725,7 +727,10 @@ ] }, "effect": [ - { "u_add_effect": "flask_regeneration", "duration": { "math": [ "( 150 + (u_spell_level('druid_healing') * 30)) " ] } } + { + "u_add_effect": "flask_regeneration", + "duration": { "math": [ "( 150 + (u_spell_level('druid_healing') * 30)) * ( restoration_proficiency_modifier() )" ] } + } ], "false_effect": [ { "u_message": "You must be surrounded by nature to use its power to heal.", "type": "bad" } ] }, @@ -738,18 +743,18 @@ "valid_targets": [ "self" ], "effect": "attack", "shape": "blast", - "flags": [ "CONCENTRATE", "SOMATIC", "VERBAL", "NO_LEGS" ], + "flags": [ "RESTORATION_SPELL", "CONCENTRATE", "SOMATIC", "VERBAL", "NO_LEGS" ], "energy_source": "MANA", "spell_class": "DRUID", "min_damage": -5, "max_damage": -20, "damage_increment": -1, "difficulty": 5, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(800, 5)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(400, 2)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(150, 2)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-16.7, 0.07)" ] }, - "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], + "base_casting_time": 800, + "base_energy_cost": 400, + "final_energy_cost": 150, + "energy_increment": -16.7, + "extra_effects": [ { "id": "eoc_restoration_setup", "hit_self": true } ], "max_level": 15 }, { @@ -758,16 +763,16 @@ "name": "Vegetative Poultice", "description": "This spell turns a mixture of bark and leaves into a powerful salve capable of stopping even grievous wounds from bleeding.", "valid_targets": [ "none" ], - "flags": [ "CONCENTRATE", "SOMATIC", "VERBAL", "NO_LEGS" ], + "flags": [ "TRANSFORMATION_SPELL", "CONCENTRATE", "SOMATIC", "VERBAL", "NO_LEGS" ], "min_damage": 1, "max_damage": 1, "effect": "spawn_item", "effect_str": "druid_bandages", "components": "spell_components_druid_bandage", "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(400, 5)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(450, 5)" ] }, - "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], + "base_casting_time": 400, + "base_energy_cost": 450, + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ], "min_duration": 48000, "max_duration": 720000, "duration_increment": 44800, @@ -782,7 +787,7 @@ "name": "Whisper of the Leaves", "description": "This spell allows you to hear the trees' wisdom in the rustle of the leaves and the creaking of their roots, discerning the layout of the forest.", "valid_targets": [ "self" ], - "flags": [ "CONCENTRATE", "VERBAL", "SOMATIC" ], + "flags": [ "CHANNELING_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC" ], "effect": "effect_on_condition", "effect_str": "EOC_GAIN_WHISPER_LEAVES", "shape": "blast", @@ -790,12 +795,12 @@ "spell_class": "DRUID", "difficulty": 6, "max_level": 15, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(6000, 10)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1000, 10)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-350, 0.07)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800, 5)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(500, 5)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-40, 0.133)" ] }, + "base_casting_time": 6000, + "final_casting_time": 1000, + "casting_time_increment": -350, + "base_energy_cost": 800, + "final_energy_cost": 500, + "energy_increment": -40, "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], "min_duration": 6000, "max_duration": 6000 @@ -827,7 +832,7 @@ "name": "Harvest of the Hunter", "description": "This spell creates a grouping of odd-looking but functional arrows out of forest detritus.", "valid_targets": [ "none" ], - "flags": [ "CONCENTRATE", "NO_HANDS", "VERBAL", "NO_LEGS" ], + "flags": [ "TRANSFORMATION_SPELL", "CONCENTRATE", "NO_HANDS", "VERBAL", "NO_LEGS" ], "spell_class": "DRUID", "difficulty": 4, "max_level": 15, @@ -842,11 +847,11 @@ "final_casting_time": 600, "casting_time_increment": -360, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(250, 4)" ] }, - "min_duration": { "math": [ "channeling_proficiency_bonus_calculate(180000, 1000)" ] }, - "max_duration": { "math": [ "channeling_proficiency_bonus_calculate(1440000, 1000)" ] }, - "duration_increment": { "math": [ "channeling_proficiency_bonus_calculate(84000, 0.07)" ] }, - "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ] + "base_energy_cost": 250, + "min_duration": 180000, + "max_duration": 1440000, + "duration_increment": 84000, + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ] }, { "id": "druid_summon_tanglevine", @@ -854,7 +859,7 @@ "name": "Summon Tanglevine", "description": "This spell causes an animated vine to burst from the ground and attempt to seize a nearby target and hold it fast.", "valid_targets": [ "ground" ], - "flags": [ "VERBAL", "SOMATIC" ], + "flags": [ "CONJURATION_SPELL", "VERBAL", "SOMATIC" ], "effect": "summon", "effect_str": "mon_tanglevine", "shape": "blast", @@ -868,12 +873,12 @@ "range_increment": 0.8, "base_casting_time": 250, "energy_source": "MANA", - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(12000, 300)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(42000, 300)" ] }, - "duration_increment": { "math": [ "summoning_proficiency_bonus_calculate(2000, 0.066)" ] }, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(650, 2)" ] }, - "final_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(400, 2)" ] }, - "energy_increment": { "math": [ "summoning_proficiency_negate_calculate(-16.666, 0.066)" ] }, + "min_duration": 12000, + "max_duration": 42000, + "duration_increment": 2000, + "base_energy_cost": 650, + "final_energy_cost": 400, + "energy_increment": -16.666, "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ] }, { @@ -882,16 +887,16 @@ "name": "Beguiling the Savage Beast", "description": "Using your connection to nature, you can sway an animal to your service. This spell even works on mutated animals.", "valid_targets": [ "hostile" ], - "flags": [ "VERBAL", "SOMATIC", "SILENT" ], + "flags": [ "ENERVATION_SPELL", "VERBAL", "SOMATIC", "SILENT" ], "effect": "charm_monster", "shape": "blast", "spell_class": "DRUID", "difficulty": 9, "max_level": 15, - "min_damage": { "math": [ "evocation_proficiency_bonus_calculate(30, 0.5)" ] }, - "max_damage": { "math": [ "evocation_proficiency_bonus_calculate(400, 0.5)" ] }, - "damage_increment": { "math": [ "evocation_proficiency_bonus_calculate(25, 0.07)" ] }, - "extra_effects": [ { "id": "eoc_evocation_setup", "hit_self": true } ], + "min_damage": 30, + "max_damage": 400, + "damage_increment": 25, + "extra_effects": [ { "id": "eoc_enervation_setup", "hit_self": true } ], "min_range": 5, "max_range": 30, "range_increment": 1.67, @@ -911,7 +916,7 @@ "name": "Spear of Brambles", "description": "This spell turns a stick into a vicious spear that drips with sticky sap.", "valid_targets": [ "none" ], - "flags": [ "CONCENTRATE", "VERBAL", "NO_HANDS" ], + "flags": [ "TRANSFORMATION_SPELL", "CONCENTRATE", "VERBAL", "NO_HANDS" ], "//": "NO_HANDS so you can hold on to the stick and cast the spell and then be holding the spear", "effect": "spawn_item", "effect_str": "druid_bramble_spear_item", @@ -924,11 +929,11 @@ "max_damage": 1, "max_level": 15, "base_casting_time": 1000, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(350, 2)" ] }, - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(24000, 200)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(360000, 200)" ] }, - "duration_increment": { "math": [ "summoning_proficiency_bonus_calculate(24000, 0.071)" ] }, - "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], + "base_energy_cost": 350, + "min_duration": 24000, + "max_duration": 360000, + "duration_increment": 24000, + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ], "learn_spells": { "druid_bramble_spear_enhanced": 15 } }, { @@ -937,7 +942,7 @@ "name": "Enhanced Spear of Brambles", "description": "This spell turns a bit of bark or a twig into a vicious spear that drips with sticky sap. You now know this spell like the back of your hand, and no longer need such massive spell components as you did previously.", "valid_targets": [ "none" ], - "flags": [ "CONCENTRATE", "VERBAL", "NO_HANDS", "NO_FAIL" ], + "flags": [ "TRANSFORMATION_SPELL", "CONCENTRATE", "VERBAL", "NO_HANDS", "NO_FAIL" ], "effect": "spawn_item", "effect_str": "druid_bramble_spear_item", "shape": "blast", @@ -948,11 +953,11 @@ "max_damage": 1, "max_level": 15, "base_casting_time": 1000, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(250, 2)" ] }, - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(360000, 400)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(2160000, 400)" ] }, - "duration_increment": { "math": [ "summoning_proficiency_bonus_calculate(72000, 0.04)" ] }, - "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ] + "base_energy_cost": 250, + "min_duration": 360000, + "max_duration": 2160000, + "duration_increment": 72000, + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ] }, { "id": "druid_summon_brambles", @@ -963,7 +968,7 @@ "effect": "effect_on_condition", "effect_str": "EOC_DRUID_BRAMBLES_SELECTOR", "shape": "blast", - "flags": [ "SOMATIC", "VERBAL" ], + "flags": [ "EVOCATION_SPELL", "SOMATIC", "VERBAL" ], "spell_class": "DRUID", "energy_source": "MANA", "difficulty": 5, @@ -1003,14 +1008,14 @@ "effect": "ter_transform", "effect_str": "druid_summoned_brambles", "shape": "cone", - "flags": [ "SILENT", "NO_PROJECTILE" ], + "flags": [ "EVOCATION_SPELL", "SILENT", "NO_PROJECTILE" ], "spell_class": "DRUID", "energy_source": "MANA", "max_level": 15, - "min_range": { "math": [ "( (u_spell_level('druid_summon_brambles') * 0.6) + evocation_proficiency_bonus_calculate(1, 0.1))" ] }, - "max_range": { "math": [ "( (u_spell_level('druid_summon_brambles') * 0.6) + evocation_proficiency_bonus_calculate(1, 0.1))" ] }, - "min_aoe": { "math": [ "( (u_spell_level('druid_summon_brambles') * 1.9) + evocation_proficiency_bonus_calculate(30, 0.3))" ] }, - "max_aoe": { "math": [ "( (u_spell_level('druid_summon_brambles') * 1.9) + evocation_proficiency_bonus_calculate(30, 0.3))" ] } + "min_range": { "math": [ "(u_spell_level('druid_summon_brambles') * 0.6) * ( evocation_proficiency_modifier() )" ] }, + "max_range": { "math": [ "(u_spell_level('druid_summon_brambles') * 0.6) * ( evocation_proficiency_modifier() )" ] }, + "min_aoe": { "math": [ "(u_spell_level('druid_summon_brambles') * 1.9) * ( evocation_proficiency_modifier() )" ] }, + "max_aoe": { "math": [ "(u_spell_level('druid_summon_brambles') * 1.9) * ( evocation_proficiency_modifier() )" ] } }, { "id": "druid_summon_brambles_line", @@ -1021,12 +1026,12 @@ "effect": "ter_transform", "effect_str": "druid_summoned_brambles", "shape": "line", - "flags": [ "SILENT", "NO_PROJECTILE" ], + "flags": [ "EVOCATION_SPELL", "SILENT", "NO_PROJECTILE" ], "spell_class": "DRUID", "energy_source": "MANA", "max_level": 15, - "min_range": { "math": [ "( (u_spell_level('druid_summon_brambles') * 1) + evocation_proficiency_bonus_calculate(1, 0.1))" ] }, - "max_range": { "math": [ "( (u_spell_level('druid_summon_brambles') * 1) + evocation_proficiency_bonus_calculate(1, 0.1))" ] } + "min_range": { "math": [ "(u_spell_level('druid_summon_brambles') * 1) * ( evocation_proficiency_modifier() )" ] }, + "max_range": { "math": [ "(u_spell_level('druid_summon_brambles') * 1) * ( evocation_proficiency_modifier() )" ] } }, { "id": "druid_thorn_skin", @@ -1034,7 +1039,7 @@ "name": "Thornskin", "description": "This spell transforms the druid's skin into a bark-like material covered in large thorns. It provides excellent protection but slightly slows you and makes you vulnerable to fire.", "valid_targets": [ "self" ], - "flags": [ "CONCENTRATE", "VERBAL", "SOMATIC" ], + "flags": [ "TRANSFORMATION_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC" ], "effect": "spawn_item", "effect_str": "druid_thorn_skin_item", "shape": "blast", @@ -1046,17 +1051,17 @@ "max_level": 15, "base_casting_time": 600, "base_energy_cost": 500, - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(24000, 200)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(360000, 200)" ] }, - "duration_increment": { "math": [ "summoning_proficiency_bonus_calculate(24000, 0.071)" ] }, - "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ] + "min_duration": 24000, + "max_duration": 360000, + "duration_increment": 24000, + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ] }, { "id": "druid_renew_forest_spell", "type": "SPELL", "name": "Renewing the Forest", "description": "While outdoors and not underground, the druid can create a profusion of life around themselves, causing grass to grow through pavement, bushes and flowers to sprout, and trees to grow to full height in moments.", - "flags": [ "SOMATIC", "VERBAL" ], + "flags": [ "CHANNELING_SPELL", "SOMATIC", "VERBAL" ], "valid_targets": [ "self" ], "max_level": 25, "spell_class": "DRUID", @@ -1065,8 +1070,8 @@ "effect": "effect_on_condition", "effect_str": "EOC_DRUID_RENEW_FOREST_SPELL", "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1500, 10)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(6000, 10)" ] }, + "base_energy_cost": 1500, + "base_casting_time": 6000, "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ] }, { @@ -1093,20 +1098,24 @@ "type": "SPELL", "name": "Renewing the Forest Real", "description": "The actual spell that casts Renewing the Forest. It's a bug if you have it.", - "flags": [ "SILENT", "VERBAL", "IGNORE_WALLS" ], + "flags": [ "CHANNELING_SPELL", "SILENT", "VERBAL", "IGNORE_WALLS" ], "valid_targets": [ "ground" ], "shape": "blast", "effect": "ter_transform", "effect_str": "ter_druid_renew_forest", - "min_aoe": { "math": [ "(u_spell_level('druid_renew_forest_spell') * rng(0.8,1.2) ) + rng(1.5,4)" ] }, - "max_aoe": { "math": [ "(u_spell_level('druid_renew_forest_spell') * rng(0.8,1.2) ) + rng(1.5,4)" ] } + "min_aoe": { + "math": [ "((u_spell_level('druid_renew_forest_spell') * rng(0.8,1.2) ) + rng(1.5,4)) * channeling_proficiency_modifier()" ] + }, + "max_aoe": { + "math": [ "((u_spell_level('druid_renew_forest_spell') * rng(0.8,1.2) ) + rng(1.5,4)) * channeling_proficiency_modifier()" ] + } }, { "id": "druid_wood_living_tree_spell", "type": "SPELL", "name": "Shape Wood", "description": "Using druidic magic, shape living wood into a log that you can use for other projects without harming the tree. You must cast this spell on a living tree.", - "flags": [ "CONCENTRATE", "SILENT", "VERBAL" ], + "flags": [ "CHANNELING_SPELL", "CONCENTRATE", "SILENT", "VERBAL" ], "valid_targets": [ "self" ], "spell_class": "DRUID", "difficulty": 5, @@ -1115,8 +1124,8 @@ "effect_str": "EOC_EOC_DRUID_SHAPE_WOOD", "shape": "blast", "energy_source": "MANA", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(180000, 1000)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(600, 5)" ] }, + "base_casting_time": 180000, + "base_energy_cost": 600, "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ] }, { @@ -1151,20 +1160,20 @@ "description": "Draw on some of the essence of water, providing protection against the summer's heat.", "valid_targets": [ "self" ], "spell_class": "DRUID", - "flags": [ "CONCENTRATE", "VERBAL", "SOMATIC" ], + "flags": [ "ENHANCEMENT_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC" ], "effect": "attack", "effect_str": "effect_druid_anti_heat", "shape": "blast", "components": "spell_components_druid_anti_heat", "difficulty": 2, "max_level": 15, - "min_duration": { "math": [ "enhancement_proficiency_bonus_calculate(90000, 5400)" ] }, - "max_duration": { "math": [ "enhancement_proficiency_bonus_calculate(900000, 5400)" ] }, - "duration_increment": { "math": [ "enhancement_proficiency_bonus_calculate(54000, 0.07)" ] }, + "min_duration": 90000, + "max_duration": 900000, + "duration_increment": 54000, "energy_source": "MANA", "base_energy_cost": 200, "extra_effects": [ { "id": "eoc_enhancement_setup", "hit_self": true } ], - "base_casting_time": { "math": [ "enhancement_proficiency_negate_calculate(6000, 40)" ] } + "base_casting_time": 6000 }, { "id": "druid_breathing_underwater", @@ -1182,11 +1191,11 @@ "spell_class": "DRUID", "difficulty": 5, "max_level": 10, - "base_casting_time": { "math": [ "enhancement_proficiency_negate_calculate(3000, 20)" ] }, + "base_casting_time": 3000, "base_energy_cost": 350, - "min_duration": { "math": [ "enhancement_proficiency_bonus_calculate(36000, 2160)" ] }, - "max_duration": { "math": [ "enhancement_proficiency_bonus_calculate(360000, 2160)" ] }, - "duration_increment": { "math": [ "enhancement_proficiency_bonus_calculate(36000, 0.11)" ] }, + "min_duration": 36000, + "max_duration": 360000, + "duration_increment": 36000, "extra_effects": [ { "id": "eoc_enhancement_setup", "hit_self": true } ] }, { @@ -1197,7 +1206,7 @@ "//": "Using spawn_item with a liquid just dumps it on the floor at the moment. Once that's fixed, this can be extended so it can be used on NPCs.", "valid_targets": [ "self" ], "spell_class": "DRUID", - "flags": [ "CONCENTRATE", "VERBAL", "SOMATIC" ], + "flags": [ "TRANSFORMATION_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC" ], "effect": "effect_on_condition", "effect_str": "EOC_DRUID_DISINFECTANT", "shape": "blast", @@ -1205,9 +1214,9 @@ "difficulty": 4, "max_level": 15, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(200, 1)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1000, 10)" ] }, - "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ] + "base_energy_cost": 200, + "base_casting_time": 1000, + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ] }, { "type": "effect_on_condition", @@ -1233,7 +1242,7 @@ "name": "Water Strider's Walk", "description": "Enchant yourself so that the water will buoy you up and prevent you from sinking, allowing you to walk on its surface.", "valid_targets": [ "self" ], - "flags": [ "CONCENTRATE", "VERBAL", "SOMATIC", "NO_LEGS" ], + "flags": [ "ENHANCEMENT_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC", "NO_LEGS" ], "effect": "attack", "effect_str": "effect_druid_water_walking", "shape": "blast", @@ -1241,11 +1250,11 @@ "spell_class": "DRUID", "difficulty": 4, "max_level": 15, - "base_casting_time": { "math": [ "enhancement_proficiency_negate_calculate(250, 2)" ] }, + "base_casting_time": 250, "base_energy_cost": 250, - "min_duration": { "math": [ "enhancement_proficiency_bonus_calculate(30000, 3000)" ] }, - "max_duration": { "math": [ "enhancement_proficiency_bonus_calculate(480000, 3000)" ] }, - "duration_increment": { "math": [ "enhancement_proficiency_bonus_calculate(30000, 0.07)" ] }, + "min_duration": 30000, + "max_duration": 480000, + "duration_increment": 30000, "extra_effects": [ { "id": "eoc_enhancement_setup", "hit_self": true } ] }, { @@ -1255,18 +1264,18 @@ "description": "Blend in the wilds and urge them to speed your passage. Trees bend out of the way, bushes do not hinder you, and even grass subtly moves your feet along. The spell cannot be cast near civilization and similarly will fade if your travels take you out of the wilds.", "valid_targets": [ "self" ], "spell_class": "DRUID", - "flags": [ "CONCENTRATE", "VERBAL", "SOMATIC" ], + "flags": [ "ENHANCEMENT_SPELL", "CONCENTRATE", "VERBAL", "SOMATIC" ], "effect": "effect_on_condition", "effect_str": "EOC_DRUID_TRAVERSE_THE_WILDS", "shape": "blast", "difficulty": 3, "max_level": 15, - "min_duration": { "math": [ "enhancement_proficiency_bonus_calculate(90000, 9000)" ] }, - "max_duration": { "math": [ "enhancement_proficiency_bonus_calculate(1440000, 9000)" ] }, - "duration_increment": { "math": [ "enhancement_proficiency_bonus_calculate(90000, 0.07)" ] }, + "min_duration": 90000, + "max_duration": 1440000, + "duration_increment": 90000, "energy_source": "MANA", "base_energy_cost": 150, - "base_casting_time": { "math": [ "enhancement_proficiency_negate_calculate(250, 2)" ] }, + "base_casting_time": 250, "extra_effects": [ { "id": "eoc_enhancement_setup", "hit_self": true } ] }, { @@ -1288,7 +1297,7 @@ "effect": [ { "u_add_effect": "effect_druid_traverse_the_wilds", - "duration": { "math": [ "( 900 + (u_spell_level('druid_traverse_the_wilds') * 900)) " ] } + "duration": { "math": [ "( 900 + (u_spell_level('druid_traverse_the_wilds') * 900)) * enhancement_proficiency_modifier()" ] } } ], "false_effect": [ { "u_message": "You must be surrounded by the wilds to traverse them.", "type": "bad" } ] @@ -1330,19 +1339,19 @@ "effect": "spawn_item", "effect_str": "aura_bearmantle", "shape": "blast", - "flags": [ "SOMATIC", "VERBAL" ], + "flags": [ "TRANSFORMATION_SPELL", "SOMATIC", "VERBAL" ], "components": "spell_components_feralform", "spell_class": "DRUID", "energy_source": "MANA", "difficulty": 4, - "base_casting_time": { "math": [ "enhancement_proficiency_negate_calculate(1500, 20)" ] }, + "base_casting_time": 1500, "base_energy_cost": 200, "max_level": 15, "min_damage": 1, "max_damage": 1, - "min_duration": { "math": [ "enhancement_proficiency_bonus_calculate(96000, 8960)" ] }, - "max_duration": { "math": [ "enhancement_proficiency_bonus_calculate(1440000, 8960)" ] }, - "duration_increment": { "math": [ "enhancement_proficiency_bonus_calculate(96000, 0.07)" ] }, - "extra_effects": [ { "id": "eoc_enhancement_setup", "hit_self": true } ] + "min_duration": 96000, + "max_duration": 1440000, + "duration_increment": 96000, + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ] } ] diff --git a/data/mods/Magiclysm/Spells/earthshaper.json b/data/mods/Magiclysm/Spells/earthshaper.json index de001fe49a0f9..f3aaa28b9e7a5 100644 --- a/data/mods/Magiclysm/Spells/earthshaper.json +++ b/data/mods/Magiclysm/Spells/earthshaper.json @@ -5,7 +5,7 @@ "name": "Stonefist", "description": "Encases your arms and hands in a sheath of magical stone, you can punch and defend yourself with it in melee combat.", "valid_targets": [ "self" ], - "flags": [ "SOMATIC", "LOUD" ], + "flags": [ "CONJURATION_SPELL", "SOMATIC", "LOUD" ], "min_damage": 1, "max_damage": 1, "effect": "spawn_item", @@ -16,10 +16,10 @@ "difficulty": 2, "max_level": 15, "base_casting_time": 200, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(100, 1)" ] }, - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(24000, 200)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(360000, 200)" ] }, - "duration_increment": { "math": [ "summoning_proficiency_bonus_calculate(24000, 0.04)" ] }, + "base_energy_cost": 100, + "min_duration": 24000, + "max_duration": 360000, + "duration_increment": 24000, "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], "learn_spells": { "stonefist_plus": 15 } }, @@ -29,7 +29,7 @@ "name": "Improved Stonefist", "description": "Encases your arms and hands in a sheath of magical stone, you can punch and defend yourself with it in melee combat. Now you know this spell like the back of your hand, and have started to design your own version.", "valid_targets": [ "self" ], - "flags": [ "SOMATIC", "NO_FAIL" ], + "flags": [ "CONJURATION_SPELL", "SOMATIC", "NO_FAIL" ], "min_damage": 1, "max_damage": 1, "effect": "spawn_item", @@ -43,12 +43,12 @@ "final_casting_time": 50, "casting_time_increment": -6, "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(100, 0.5)" ] }, - "final_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(50, 0.5)" ] }, - "energy_increment": { "math": [ "summoning_proficiency_negate_calculate(-2, 0.04)" ] }, - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(360000, 400)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(2160000, 400)" ] }, - "duration_increment": { "math": [ "summoning_proficiency_bonus_calculate(72000, 0.07)" ] } + "base_energy_cost": 100, + "final_energy_cost": 50, + "energy_increment": -2, + "min_duration": 360000, + "max_duration": 2160000, + "duration_increment": 72000 }, { "id": "seismic_stomp", @@ -59,18 +59,18 @@ "effect_str": "downed", "shape": "blast", "valid_targets": [ "hostile", "ground", "none" ], - "flags": [ "SOMATIC", "LOUD", "NO_PROJECTILE" ], + "flags": [ "EVOCATION_SPELL", "SOMATIC", "LOUD", "NO_PROJECTILE" ], "extra_effects": [ { "id": "eoc_evocation_setup", "hit_self": true } ], "max_level": 10, - "min_damage": { "math": [ "evocation_proficiency_bonus_calculate(2, 0.2)" ] }, - "max_damage": { "math": [ "evocation_proficiency_bonus_calculate(10, 0.2)" ] }, - "damage_increment": { "math": [ "evocation_proficiency_bonus_calculate(0.8, 0.1)" ] }, + "min_damage": 2, + "max_damage": 10, + "damage_increment": 0.8, "min_aoe": 3, "max_aoe": 12, "aoe_increment": 1, - "min_duration": { "math": [ "evocation_proficiency_bonus_calculate(1000, 10)" ] }, - "max_duration": { "math": [ "evocation_proficiency_bonus_calculate(6000, 10)" ] }, - "duration_increment": { "math": [ "evocation_proficiency_bonus_calculate(500, 0.1)" ] }, + "min_duration": 1000, + "max_duration": 6000, + "duration_increment": 500, "spell_class": "EARTHSHAPER", "base_casting_time": 100, "base_energy_cost": 250, @@ -87,21 +87,21 @@ "effect_str": "STAMINA", "shape": "blast", "valid_targets": [ "self" ], - "flags": [ "NO_HANDS", "CONCENTRATE", "SILENT" ], + "flags": [ "RESTORATION_SPELL", "NO_HANDS", "CONCENTRATE", "SILENT" ], "min_damage": 1500, "max_damage": 10000, "damage_increment": 750, "max_level": 12, "spell_class": "EARTHSHAPER", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(500, 3)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(300, 3)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-17, 0.085)" ] }, + "base_casting_time": 500, + "final_casting_time": 300, + "casting_time_increment": -17, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(150, 5)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(75, 0.09)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(1000, 5)" ] }, + "base_energy_cost": 150, + "energy_increment": 75, + "final_energy_cost": 1000, "difficulty": 5, - "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ] + "extra_effects": [ { "id": "eoc_restoration_setup", "hit_self": true } ] }, { "id": "eshaper_shardspray", @@ -109,7 +109,7 @@ "name": "Shardspray", "description": "This spell projects a wide spray of sharp metal shards, cutting into your foes and friends alike.", "valid_targets": [ "hostile", "ground", "ally" ], - "flags": [ "SOMATIC", "LOUD", "NO_HANDS" ], + "flags": [ "EVOCATION_SPELL", "SOMATIC", "LOUD", "NO_HANDS" ], "components": "spell_components_shardspray", "effect": "attack", "shape": "cone", @@ -119,9 +119,9 @@ "base_casting_time": 100, "base_energy_cost": 100, "max_level": 20, - "min_damage": { "math": [ "evocation_proficiency_bonus_calculate(30, 0.5)" ] }, - "max_damage": { "math": [ "evocation_proficiency_bonus_calculate(80, 0.5)" ] }, - "damage_increment": { "math": [ "evocation_proficiency_bonus_calculate(2.5, 0.05)" ] }, + "min_damage": 30, + "max_damage": 80, + "damage_increment": 2.5, "extra_effects": [ { "id": "eoc_evocation_setup", "hit_self": true } ], "damage_type": "cut", "min_aoe": 25, @@ -140,7 +140,7 @@ "name": "Piercing Bolt", "description": "This spell projects a piercing rod of conjured iron at those that dare oppose you.", "valid_targets": [ "hostile" ], - "flags": [ "SOMATIC", "LOUD" ], + "flags": [ "EVOCATION_SPELL", "SOMATIC", "LOUD" ], "effect": "attack", "shape": "blast", "spell_class": "EARTHSHAPER", @@ -149,9 +149,9 @@ "base_energy_cost": 115, "difficulty": 2, "max_level": 20, - "min_damage": { "math": [ "evocation_proficiency_bonus_calculate(20, 0.5)" ] }, - "max_damage": { "math": [ "evocation_proficiency_bonus_calculate(50, 0.5)" ] }, - "damage_increment": { "math": [ "evocation_proficiency_bonus_calculate(3, 0.1)" ] }, + "min_damage": 20, + "max_damage": 50, + "damage_increment": 3, "extra_effects": [ { "id": "eoc_evocation_setup", "hit_self": true } ], "damage_type": "stab", "min_range": 8, @@ -164,10 +164,10 @@ "name": "Shardstorm", "description": "Creates an omnidirectional spray of razor sharp metal shards all around you.", "valid_targets": [ "hostile", "ally", "ground" ], - "flags": [ "SOMATIC", "LOUD" ], - "min_damage": { "math": [ "evocation_proficiency_bonus_calculate(20, 0.5)" ] }, - "max_damage": { "math": [ "evocation_proficiency_bonus_calculate(60, 0.5)" ] }, - "damage_increment": { "math": [ "evocation_proficiency_bonus_calculate(2.0, 0.05)" ] }, + "flags": [ "EVOCATION_SPELL", "SOMATIC", "LOUD" ], + "min_damage": 20, + "max_damage": 60, + "damage_increment": 2.0, "extra_effects": [ { "id": "eoc_evocation_setup", "hit_self": true } ], "damage_type": "cut", "min_aoe": 1, @@ -188,11 +188,11 @@ "name": "Rockbolt", "description": "Fires a conjured stone projectile at high velocity.", "valid_targets": [ "hostile", "ally" ], - "flags": [ "SOMATIC", "LOUD" ], - "min_damage": { "math": [ "evocation_proficiency_bonus_calculate(5, 0.2)" ] }, - "damage_increment": { "math": [ "evocation_proficiency_bonus_calculate(1.5, 0.07)" ] }, + "flags": [ "EVOCATION_SPELL", "SOMATIC", "LOUD" ], + "min_damage": 5, + "damage_increment": 1.5, "damage_type": "bash", - "max_damage": { "math": [ "evocation_proficiency_bonus_calculate(26, 0.2)" ] }, + "max_damage": 26, "min_range": 5, "range_increment": 0.5, "max_range": 15, @@ -212,7 +212,7 @@ "name": "Move Earth", "description": "Your essence flows around you, and the earth follows.", "valid_targets": [ "hostile", "ally", "ground", "self" ], - "flags": [ "SOMATIC", "LOUD", "NO_PROJECTILE" ], + "flags": [ "CHANNELING_SPELL", "SOMATIC", "LOUD", "NO_PROJECTILE" ], "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], "min_aoe": 1, "max_aoe": 2, @@ -220,15 +220,15 @@ "max_damage": 1, "damage_increment": -5, "aoe_increment": 0.25, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(200, 2)" ] }, + "base_energy_cost": 200, "spell_class": "EARTHSHAPER", "difficulty": 4, "max_level": 20, "min_range": 5, "max_range": 5, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1200, 3)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(200, 3)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-50, 0.05)" ] }, + "base_casting_time": 1200, + "final_casting_time": 200, + "casting_time_increment": -50, "energy_source": "MANA", "shape": "blast", "effect": "ter_transform", @@ -245,7 +245,7 @@ "effect": "spawn_item", "effect_str": "rune_earthshaper", "shape": "blast", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(5000, 10)" ] }, + "base_casting_time": 5000, "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], "base_energy_cost": 5, "min_duration": 1, @@ -255,7 +255,7 @@ "max_level": 0, "spell_class": "EARTHSHAPER", "energy_source": "MANA", - "flags": [ "PERMANENT", "NO_LEGS", "CONCENTRATE" ] + "flags": [ "CHANNELING_SPELL", "PERMANENT", "NO_LEGS", "CONCENTRATE" ] }, { "id": "clairvoyance", @@ -265,15 +265,15 @@ "effect": "attack", "shape": "blast", "valid_targets": [ "ally", "hostile", "ground" ], - "flags": [ "SOMATIC", "VERBAL", "IGNORE_WALLS", "NO_PROJECTILE" ], + "flags": [ "CHANNELING_SPELL", "SOMATIC", "VERBAL", "IGNORE_WALLS", "NO_PROJECTILE" ], "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], "max_level": 20, "min_aoe": 4, "max_aoe": 13, "aoe_increment": 0.5, "spell_class": "EARTHSHAPER", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(350, 5)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(750, 5)" ] }, + "base_casting_time": 350, + "base_energy_cost": 750, "energy_source": "MANA", "difficulty": 4, "field_id": "fd_clairvoyant", @@ -289,18 +289,18 @@ "effect": "spawn_item", "effect_str": "aura_stoneskin", "shape": "blast", - "flags": [ "SOMATIC", "LOUD" ], + "flags": [ "CONJURATION_SPELL", "SOMATIC", "LOUD" ], "spell_class": "EARTHSHAPER", "energy_source": "MANA", "difficulty": 4, "base_casting_time": 300, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(300, 2)" ] }, + "base_energy_cost": 300, "max_level": 15, "min_damage": 1, "max_damage": 1, - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(24000, 200)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(360000, 200)" ] }, - "duration_increment": { "math": [ "summoning_proficiency_bonus_calculate(24000, 0.04)" ] }, + "min_duration": 24000, + "max_duration": 360000, + "duration_increment": 24000, "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], "learn_spells": { "earthshaper_stoneskin_plus": 15 } }, @@ -313,22 +313,22 @@ "effect": "spawn_item", "effect_str": "aura_stoneskin", "shape": "blast", - "flags": [ "SOMATIC", "LOUD", "NO_FAIL" ], + "flags": [ "CONJURATION_SPELL", "SOMATIC", "LOUD", "NO_FAIL" ], "spell_class": "EARTHSHAPER", "energy_source": "MANA", "difficulty": 6, "base_casting_time": 300, "final_casting_time": 100, "casting_time_increment": -8, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(300, 1)" ] }, - "final_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(100, 1)" ] }, - "energy_increment": { "math": [ "summoning_proficiency_negate_calculate(-8, 0.04)" ] }, + "base_energy_cost": 300, + "final_energy_cost": 100, + "energy_increment": -8, "max_level": 25, "min_damage": 1, "max_damage": 1, - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(360000, 400)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(2160000, 400)" ] }, - "duration_increment": { "math": [ "summoning_proficiency_bonus_calculate(72000, 0.071)" ] }, + "min_duration": 360000, + "max_duration": 2160000, + "duration_increment": 72000, "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ] }, { @@ -341,14 +341,14 @@ "effect_str": "earthshaper_pillar", "shape": "blast", "extra_effects": [ { "id": "earthshaper_pillar_side_effect" }, { "id": "eoc_channeling_setup", "hit_self": true } ], - "flags": [ "SOMATIC", "LOUD", "NO_PROJECTILE" ], + "flags": [ "CHANNELING_SPELL", "SOMATIC", "LOUD", "NO_PROJECTILE" ], "spell_class": "EARTHSHAPER", "energy_source": "MANA", "difficulty": 3, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(30000, 50)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(6000, 50)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-2400, 0.1)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(500, 5)" ] }, + "base_casting_time": 30000, + "final_casting_time": 6000, + "casting_time_increment": -2400, + "base_energy_cost": 500, "max_level": 10, "min_range": 3, "max_range": 6, @@ -377,13 +377,13 @@ "name": "Petrifying Touch", "description": "Your hands tries to transform the body of your enemy into a pure stone. The effect is temporary, but it can deal significant damage.", "valid_targets": [ "hostile" ], - "flags": [ "NO_PROJECTILE", "SILENT", "NO_HANDS" ], + "flags": [ "EVOCATION_SPELL", "NO_PROJECTILE", "SILENT", "NO_HANDS" ], "effect": "attack", "shape": "blast", "damage_type": "necrotic", - "min_damage": { "math": [ "evocation_proficiency_bonus_calculate(10, 0.5)" ] }, - "damage_increment": { "math": [ "evocation_proficiency_bonus_calculate(2, 0.06)" ] }, - "max_damage": { "math": [ "evocation_proficiency_bonus_calculate(45, 0.5)" ] }, + "min_damage": 10, + "damage_increment": 2, + "max_damage": 45, "min_range": 1, "max_range": 1, "base_energy_cost": 175, @@ -404,15 +404,15 @@ "name": "Petrifying Touch Moves Removing", "description": "Delete some amount of moves from monster, and inflict DoT. You can see it only in debug mode.", "valid_targets": [ "hostile" ], - "flags": [ "SILENT", "NO_EXPLOSION_SFX" ], + "flags": [ "EVOCATION_SPELL", "SILENT", "NO_EXPLOSION_SFX" ], "effect": "mod_moves", "shape": "blast", "min_damage": -1000, "max_damage": -1, "damage_increment": 50, - "min_dot": { "math": [ "evocation_proficiency_bonus_calculate(0, 0.2)" ] }, - "max_dot": { "math": [ "evocation_proficiency_bonus_calculate(10, 0.2)" ] }, - "dot_increment": { "math": [ "evocation_proficiency_bonus_calculate(0.5, 0.05)" ] }, + "min_dot": 0, + "max_dot": 10, + "dot_increment": 0.5, "max_level": 20 }, { @@ -425,11 +425,11 @@ "shape": "blast", "components": "spell_components_reactive_armor", "valid_targets": [ "hostile", "ground" ], - "flags": [ "SOMATIC", "LOUD", "NO_HANDS", "RANDOM_DURATION" ], + "flags": [ "EVOCATION_SPELL", "SOMATIC", "LOUD", "NO_HANDS", "RANDOM_DURATION" ], "max_level": 20, - "min_damage": { "math": [ "evocation_proficiency_bonus_calculate(20, 0.5)" ] }, - "max_damage": { "math": [ "evocation_proficiency_bonus_calculate(200, 0.5)" ] }, - "damage_increment": { "math": [ "evocation_proficiency_bonus_calculate(9, 0.05)" ] }, + "min_damage": 20, + "max_damage": 200, + "damage_increment": 9, "extra_effects": [ { "id": "eoc_evocation_setup", "hit_self": true } ], "min_aoe": 2, "max_aoe": 12, @@ -456,11 +456,11 @@ "effect": "attack", "shape": "blast", "valid_targets": [ "hostile", "ground" ], - "flags": [ "SOMATIC", "VERBAL", "NO_PROJECTILE", "NO_LEGS" ], + "flags": [ "EVOCATION_SPELL", "SOMATIC", "VERBAL", "NO_PROJECTILE", "NO_LEGS" ], "max_level": 20, - "min_damage": { "math": [ "evocation_proficiency_bonus_calculate(16, 0.5)" ] }, - "max_damage": { "math": [ "evocation_proficiency_bonus_calculate(106, 0.5)" ] }, - "damage_increment": { "math": [ "evocation_proficiency_bonus_calculate(5, 0.055)" ] }, + "min_damage": 16, + "max_damage": 106, + "damage_increment": 5, "min_aoe": 1, "max_aoe": 7, "aoe_increment": 0.3, @@ -481,7 +481,7 @@ "name": "Impalement Moves Removing", "description": "Delete some random amount of moves from monster. You can see it only in debug mode.", "valid_targets": [ "hostile" ], - "flags": [ "SILENT", "RANDOM_DAMAGE", "NO_PROJECTILE", "NO_EXPLOSION_SFX" ], + "flags": [ "EVOCATION_SPELL", "SILENT", "RANDOM_DAMAGE", "NO_PROJECTILE", "NO_EXPLOSION_SFX" ], "effect": "mod_moves", "shape": "blast", "max_level": 20, @@ -497,7 +497,7 @@ "name": "Utility Molding", "description": "Shape the basic working tools, using your own magic abilities and earth nearby. Activate to change the shape of a tool.", "valid_targets": [ "self" ], - "flags": [ "SOMATIC", "LOUD" ], + "flags": [ "CONJURATION_SPELL", "SOMATIC", "LOUD" ], "min_damage": 1, "max_damage": 1, "effect": "effect_on_condition", @@ -511,12 +511,12 @@ "base_casting_time": 360000, "final_casting_time": 90000, "casting_time_increment": -18000, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(600, 2)" ] }, - "final_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(200, 2)" ] }, - "energy_increment": { "math": [ "summoning_proficiency_negate_calculate(-30, 0.075)" ] }, - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(576000, 3000)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(8640000, 3000)" ] }, - "duration_increment": { "math": [ "summoning_proficiency_bonus_calculate(576000, 0.071)" ] } + "base_energy_cost": 600, + "final_energy_cost": 200, + "energy_increment": -30, + "min_duration": 576000, + "max_duration": 8640000, + "duration_increment": 576000 }, { "type": "effect_on_condition", @@ -573,18 +573,14 @@ "name": "Utility Molding (Hammer)", "description": "Spawn the Utility molding hammer. It's a bug if you have this spell directly.", "valid_targets": [ "self" ], - "flags": [ "SILENT", "NO_EXPLOSION_SFX" ], + "flags": [ "CONJURATION_SPELL", "SILENT", "NO_EXPLOSION_SFX" ], "min_damage": 1, "max_damage": 1, "effect": "spawn_item", "effect_str": "eshaper_hammer", "shape": "blast", - "min_duration": { - "math": [ "( (u_spell_level('eshaper_spawn_tools') * 576000) + summoning_proficiency_bonus_calculate(576000, 3000))" ] - }, - "max_duration": { - "math": [ "( (u_spell_level('eshaper_spawn_tools') * 576000) + summoning_proficiency_bonus_calculate(576000, 3000))" ] - } + "min_duration": { "math": [ "(u_spell_level('eshaper_spawn_tools') * 576000)" ] }, + "max_duration": { "math": [ "(u_spell_level('eshaper_spawn_tools') * 576000)" ] } }, { "id": "eshaper_spawn_pickaxe", @@ -592,18 +588,14 @@ "name": "Utility Molding (Pickaxe)", "description": "Spawn the Utility molding pickaxe. It's a bug if you have this spell directly.", "valid_targets": [ "self" ], - "flags": [ "SILENT", "NO_EXPLOSION_SFX" ], + "flags": [ "CONJURATION_SPELL", "SILENT", "NO_EXPLOSION_SFX" ], "min_damage": 1, "max_damage": 1, "effect": "spawn_item", "effect_str": "eshaper_pickaxe", "shape": "blast", - "min_duration": { - "math": [ "( (u_spell_level('eshaper_spawn_tools') * 576000) + summoning_proficiency_bonus_calculate(576000, 3000))" ] - }, - "max_duration": { - "math": [ "( (u_spell_level('eshaper_spawn_tools') * 576000) + summoning_proficiency_bonus_calculate(576000, 3000))" ] - } + "min_duration": { "math": [ "(u_spell_level('eshaper_spawn_tools') * 576000)" ] }, + "max_duration": { "math": [ "(u_spell_level('eshaper_spawn_tools') * 576000) " ] } }, { "id": "eshaper_spawn_axe", @@ -611,18 +603,14 @@ "name": "Utility Molding (Axe)", "description": "Spawn the Utility molding axe. It's a bug if you have this spell directly.", "valid_targets": [ "self" ], - "flags": [ "SILENT", "NO_EXPLOSION_SFX" ], + "flags": [ "CONJURATION_SPELL", "SILENT", "NO_EXPLOSION_SFX" ], "min_damage": 1, "max_damage": 1, "effect": "spawn_item", "effect_str": "eshaper_ax", "shape": "blast", - "min_duration": { - "math": [ "( (u_spell_level('eshaper_spawn_tools') * 576000) + summoning_proficiency_bonus_calculate(576000, 3000))" ] - }, - "max_duration": { - "math": [ "( (u_spell_level('eshaper_spawn_tools') * 576000) + summoning_proficiency_bonus_calculate(576000, 3000))" ] - } + "min_duration": { "math": [ "(u_spell_level('eshaper_spawn_tools') * 576000)" ] }, + "max_duration": { "math": [ "(u_spell_level('eshaper_spawn_tools') * 576000) " ] } }, { "id": "eshaper_spawn_knife", @@ -630,18 +618,14 @@ "name": "Utility Molding (Knife)", "description": "Spawn the Utility molding knife. It's a bug if you have this spell directly.", "valid_targets": [ "self" ], - "flags": [ "SILENT", "NO_EXPLOSION_SFX" ], + "flags": [ "CONJURATION_SPELL", "SILENT", "NO_EXPLOSION_SFX" ], "min_damage": 1, "max_damage": 1, "effect": "spawn_item", "effect_str": "eshaper_knife", "shape": "blast", - "min_duration": { - "math": [ "( (u_spell_level('eshaper_spawn_tools') * 576000) + summoning_proficiency_bonus_calculate(576000, 3000))" ] - }, - "max_duration": { - "math": [ "( (u_spell_level('eshaper_spawn_tools') * 576000) + summoning_proficiency_bonus_calculate(576000, 3000))" ] - } + "min_duration": { "math": [ "(u_spell_level('eshaper_spawn_tools') * 576000) " ] }, + "max_duration": { "math": [ "(u_spell_level('eshaper_spawn_tools') * 576000) " ] } }, { "id": "eshaper_spawn_shovel", @@ -649,18 +633,14 @@ "name": "Utility Molding (Shovel)", "description": "Spawn the Utility molding shovel. It's a bug if you have this spell directly.", "valid_targets": [ "self" ], - "flags": [ "SILENT", "NO_EXPLOSION_SFX" ], + "flags": [ "CONJURATION_SPELL", "SILENT", "NO_EXPLOSION_SFX" ], "min_damage": 1, "max_damage": 1, "effect": "spawn_item", "effect_str": "eshaper_shovel", "shape": "blast", - "min_duration": { - "math": [ "( (u_spell_level('eshaper_spawn_tools') * 576000) + summoning_proficiency_bonus_calculate(576000, 3000))" ] - }, - "max_duration": { - "math": [ "( (u_spell_level('eshaper_spawn_tools') * 576000) + summoning_proficiency_bonus_calculate(576000, 3000))" ] - } + "min_duration": { "math": [ "( u_spell_level('eshaper_spawn_tools') * 576000)" ] }, + "max_duration": { "math": [ "( u_spell_level('eshaper_spawn_tools') * 576000)" ] } }, { "id": "eshaper_melee_damage", @@ -671,21 +651,21 @@ "effect": "attack", "effect_str": "eshaper_melee_damage", "shape": "blast", - "flags": [ "NO_LEGS", "SILENT", "NO_EXPLOSION_SFX" ], + "flags": [ "ENHANCEMENT_SPELL", "NO_LEGS", "SILENT", "NO_EXPLOSION_SFX" ], "spell_class": "EARTHSHAPER", "energy_source": "MANA", "extra_effects": [ { "id": "eoc_enhancement_setup", "hit_self": true } ], "difficulty": 6, - "base_casting_time": { "math": [ "enhancement_proficiency_negate_calculate(1500, 6.67)" ] }, - "final_casting_time": { "math": [ "enhancement_proficiency_negate_calculate(500, 6.67)" ] }, - "casting_time_increment": { "math": [ "enhancement_proficiency_negate_calculate(-40, 0.04)" ] }, + "base_casting_time": 1500, + "final_casting_time": 500, + "casting_time_increment": -40, "base_energy_cost": 500, "final_energy_cost": 200, "energy_increment": -12, "max_level": 25, - "min_duration": { "math": [ "enhancement_proficiency_bonus_calculate(14400, 2304)" ] }, - "max_duration": { "math": [ "enhancement_proficiency_bonus_calculate(360000, 2304)" ] }, - "duration_increment": { "math": [ "enhancement_proficiency_bonus_calculate(14400, 0.042)" ] } + "min_duration": 14400, + "max_duration": 360000, + "duration_increment": 14400 }, { "id": "eshaper_crystal_wrap", @@ -696,7 +676,7 @@ "effect": "attack", "effect_str": "eshaper_crystal_wrap", "shape": "blast", - "flags": [ "NO_LEGS", "SILENT", "NO_EXPLOSION_SFX" ], + "flags": [ "CONJURATION_SPELL", "NO_LEGS", "SILENT", "NO_EXPLOSION_SFX" ], "spell_class": "EARTHSHAPER", "energy_source": "MANA", "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], @@ -704,13 +684,13 @@ "base_casting_time": 1500, "final_casting_time": 500, "casting_time_increment": -40, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(500, 1.5)" ] }, - "final_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(200, 1.5)" ] }, - "energy_increment": { "math": [ "summoning_proficiency_negate_calculate(-12, 0.04)" ] }, + "base_energy_cost": 500, + "final_energy_cost": 200, + "energy_increment": -12, "max_level": 25, - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(14400, 200)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(360000, 200)" ] }, - "duration_increment": { "math": [ "summoning_proficiency_bonus_calculate(14400, 0.042)" ] } + "min_duration": 14400, + "max_duration": 360000, + "duration_increment": 14400 }, { "type": "SPELL", @@ -719,7 +699,7 @@ "description": "Return some damage to attacker. You can see it only in debug mode.", "effect": "attack", "shape": "blast", - "flags": [ "SILENT", "RANDOM_DAMAGE", "NO_EXPLOSION_SFX" ], + "flags": [ "CONJURATION_SPELL", "SILENT", "RANDOM_DAMAGE", "NO_EXPLOSION_SFX" ], "min_damage": 13, "max_damage": 6, "valid_targets": [ "hostile" ], @@ -734,7 +714,7 @@ "description": "Hide yourself within sand-filled winds. It's harder to hit you, and monsters can't spot you. Attacking a target will break the spell.", "//": "Fuck its broken. I thought you can make monster hard to see you, so you will be able to hide from them beyond the sand, but of course invis make monsters even more dumb, and they start to stoically ignore your existence.", "valid_targets": [ "self" ], - "flags": [ "SOMATIC", "LOUD" ], + "flags": [ "ENHANCEMENT_SPELL", "SOMATIC", "LOUD" ], "effect": "attack", "effect_str": "effect_shape_of_dust", "components": "spell_components_shape_of_dust", @@ -743,12 +723,12 @@ "energy_source": "MANA", "difficulty": 7, "max_level": 25, - "base_casting_time": { "math": [ "enhancement_proficiency_negate_calculate(500, 2)" ] }, + "base_casting_time": 500, "base_energy_cost": 350, "extra_effects": [ { "id": "eoc_enhancement_setup", "hit_self": true } ], - "min_duration": { "math": [ "enhancement_proficiency_bonus_calculate(2400, 384)" ] }, - "max_duration": { "math": [ "enhancement_proficiency_bonus_calculate(60000, 384)" ] }, - "duration_increment": { "math": [ "enhancement_proficiency_bonus_calculate(2400, 0.042)" ] } + "min_duration": 2400, + "max_duration": 60000, + "duration_increment": 2400 }, { "id": "summon_eshaper_golem", @@ -765,19 +745,19 @@ "effect_str": "mon_eshaper_golem", "shape": "blast", "energy_source": "MANA", - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(750, 2)" ] }, - "final_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(400, 2)" ] }, - "energy_increment": { "math": [ "summoning_proficiency_negate_calculate(-12, 0.034)" ] }, + "base_energy_cost": 750, + "final_energy_cost": 400, + "energy_increment": -12, "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], "base_casting_time": 360000, "final_casting_time": 180000, "casting_time_increment": -6000, "min_aoe": 1, "max_aoe": 1, - "flags": [ "SOMATIC", "VERBAL", "CONCENTRATE" ], - "min_duration": { "math": [ "summoning_proficiency_bonus_calculate(12000, 200)" ] }, - "max_duration": { "math": [ "summoning_proficiency_bonus_calculate(360000, 200)" ] }, - "duration_increment": { "math": [ "summoning_proficiency_bonus_calculate(12000, 0.034)" ] } + "flags": [ "CONJURATION_SPELL", "SOMATIC", "VERBAL", "CONCENTRATE" ], + "min_duration": 12000, + "max_duration": 360000, + "duration_increment": 12000 }, { "id": "earthshaper_boulder", @@ -788,14 +768,14 @@ "effect": "ter_transform", "effect_str": "earthshaper_boulder", "shape": "blast", - "flags": [ "SOMATIC", "NO_PROJECTILE" ], + "flags": [ "CONJURATION_SPELL", "SOMATIC", "NO_PROJECTILE" ], "spell_class": "EARTHSHAPER", "energy_source": "MANA", "difficulty": 3, - "base_casting_time": { "math": [ "summoning_proficiency_negate_calculate(360000, 200)" ] }, - "final_casting_time": { "math": [ "summoning_proficiency_negate_calculate(120000, 200)" ] }, - "casting_time_increment": { "math": [ "summoning_proficiency_negate_calculate(-24000, 0.034)" ] }, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(500, 2)" ] }, + "base_casting_time": 360000, + "final_casting_time": 120000, + "casting_time_increment": -24000, + "base_energy_cost": 500, "max_level": 10, "min_range": 1, "max_range": 1, @@ -807,16 +787,16 @@ "name": "Reading the Earthbones", "description": "You extend your senses into the ground, becoming aware of every hill and valley within a large area. It will only work when in contact with the earth.", "valid_targets": [ "self" ], - "flags": [ "NO_HANDS", "CONCENTRATE", "VERBAL" ], + "flags": [ "CHANNELING_SPELL", "NO_HANDS", "CONCENTRATE", "VERBAL" ], "effect": "effect_on_condition", "effect_str": "EOC_EARTHSHAPER_MAP", - "extra_effects": [ { "id": "eoc_conveyance_setup", "hit_self": true } ], + "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], "shape": "blast", "max_level": 15, "spell_class": "EARTHSHAPER", - "base_casting_time": { "math": [ "conveyance_proficiency_negate_calculate(6000, 40)" ] }, + "base_casting_time": 6000, "energy_source": "MANA", - "base_energy_cost": { "math": [ "conveyance_proficiency_negate_calculate(1000, 6.7)" ] }, + "base_energy_cost": 1000, "difficulty": 8 }, { @@ -951,7 +931,7 @@ "description": "By sensing their movements upon the earth, you can detect nearby sources of danger. You must maintain a connection to the earth for the spell to function.", "valid_targets": [ "self" ], "spell_class": "EARTHSHAPER", - "flags": [ "CONCENTRATE", "SOMATIC", "VERBAL", "NO_EXPLOSION_SFX" ], + "flags": [ "CHANNELING_SPELL", "CONCENTRATE", "SOMATIC", "VERBAL", "NO_EXPLOSION_SFX" ], "effect": "effect_on_condition", "effect_str": "EOC_EARTHSHAPER_DANGERSENSE", "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], @@ -959,8 +939,8 @@ "energy_source": "MANA", "difficulty": 3, "max_level": 10, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(400, 5)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(350, 3)" ] }, + "base_casting_time": 400, + "base_energy_cost": 350, "min_duration": 0, "max_duration": 300000, "duration_increment": 30000 @@ -972,7 +952,7 @@ "effect": [ { "u_add_effect": "effect_tremorsense", - "duration": { "math": [ "(u_spell_level('earthshaper_danger_sense') * 300)" ] } + "duration": { "math": [ "(u_spell_level('earthshaper_danger_sense') * 300) * channeling_proficiency_modifier()" ] } } ], "false_effect": [ { "u_message": "Without a direct connection to the living earth, the spell fails.", "type": "bad" } ] @@ -996,7 +976,7 @@ "type": "SPELL", "name": "Stones' Fortitude", "description": "Draw on the eternal endurance of the stones, slowing your metabolism and staving off hunger and thirst. However, while the enchantment is in effect, you will not heal.", - "flags": [ "CONCENTRATE", "SOMATIC", "VERBAL" ], + "flags": [ "ENHANCEMENT_SPELL", "CONCENTRATE", "SOMATIC", "VERBAL" ], "valid_targets": [ "self" ], "spell_class": "EARTHSHAPER", "energy_source": "MANA", @@ -1008,16 +988,16 @@ "base_casting_time": 500, "base_energy_cost": 650, "max_level": 20, - "min_duration": { "math": [ "enhancement_proficiency_bonus_calculate(360000, 12000)" ] }, - "max_duration": { "math": [ "enhancement_proficiency_bonus_calculate(2160000, 12000)" ] }, - "duration_increment": { "math": [ "enhancement_proficiency_bonus_calculate(100000, 0.055)" ] } + "min_duration": 360000, + "max_duration": 2160000, + "duration_increment": 100000 }, { "id": "earthshaper_turning_of_earth", "type": "SPELL", "name": "The Turning of the Earth", "description": "Ask the earth spirits to prepare the earth for growth and planting.", - "flags": [ "CONCENTRATE", "SOMATIC", "VERBAL", "LOUD" ], + "flags": [ "CHANNELING_SPELL", "CONCENTRATE", "SOMATIC", "VERBAL", "LOUD" ], "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], "valid_targets": [ "ground" ], "max_level": 12, @@ -1027,10 +1007,10 @@ "difficulty": 2, "effect": "ter_transform", "effect_str": "earthshaper_turning_earth", - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1500, 5)" ] }, - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(800, 3)" ] }, - "final_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(350, 3)" ] }, - "energy_increment": { "math": [ "channeling_proficiency_negate_calculate(-37.5, 0.083)" ] }, + "base_casting_time": 1500, + "base_energy_cost": 800, + "final_energy_cost": 350, + "energy_increment": -37.5, "min_range": 3, "max_range": 20, "range_increment": 1.2 @@ -1040,7 +1020,7 @@ "type": "SPELL", "name": "Granite Aegis", "description": "In an extremity of danger, summon a hollow shell of rock around yourself. It lasts only a few moments, but sometimes that's all you need. You must be standing on the living earth to invoke it.", - "flags": [ "SOMATIC", "VERBAL" ], + "flags": [ "CONJURATION_SPELL", "SOMATIC", "VERBAL" ], "valid_targets": [ "self" ], "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], "max_level": 10, @@ -1053,7 +1033,7 @@ "base_casting_time": 150, "final_casting_time": 100, "casting_time_increment": -5, - "base_energy_cost": { "math": [ "summoning_proficiency_negate_calculate(750, 2)" ] } + "base_energy_cost": 750 }, { "type": "effect_on_condition", @@ -1136,20 +1116,20 @@ "name": "Harden Earth", "description": "Compress dirt together so it becomes as hard as rock. A great way to turn makeshift barricades into a fortress.", "valid_targets": [ "hostile", "ally", "ground", "self" ], - "flags": [ "SOMATIC", "VERBAL" ], + "flags": [ "TRANSFORMATION_SPELL", "SOMATIC", "VERBAL" ], "spell_class": "EARTHSHAPER", "difficulty": 4, "max_level": 20, "effect": "ter_transform", "effect_str": "ter_earthshaper_harden_earth", - "extra_effects": [ { "id": "eoc_channeling_setup", "hit_self": true } ], + "extra_effects": [ { "id": "eoc_transformation_setup", "hit_self": true } ], "shape": "line", "min_range": 2, "max_range": 20, "range_increment": 1, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(200, 2.5)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(1500, 10)" ] } + "base_energy_cost": 200, + "base_casting_time": 1500 }, { "id": "earthshaper_sleep_in_earth", @@ -1157,7 +1137,7 @@ "name": "Stone Slumber", "description": "When standing on earth or stone, sink into the ground. While submerged, you will heal faster, sleep will be more restorative, and you will not need to eat or drink. Cast this spell again to return to the surface.", "valid_targets": [ "self" ], - "flags": [ "CONCENTRATE", "SOMATIC", "VERBAL" ], + "flags": [ "ENHANCEMENT_SPELL", "CONCENTRATE", "SOMATIC", "VERBAL" ], "spell_class": "EARTHSHAPER", "difficulty": 8, "max_level": 20, @@ -1166,8 +1146,8 @@ "shape": "blast", "energy_source": "MANA", "extra_effects": [ { "id": "eoc_enhancement_setup", "hit_self": true } ], - "base_casting_time": { "math": [ "u_has_trait('EARTHSHAPER_STONE_SLEEP') ? 0 : enhancement_proficiency_negate_calculate(6000, 34.7)" ] }, - "base_energy_cost": { "math": [ "u_has_trait('EARTHSHAPER_STONE_SLEEP') ? 0 : enhancement_proficiency_negate_calculate(800, 34.7)" ] } + "base_casting_time": { "math": [ "u_has_trait('EARTHSHAPER_STONE_SLEEP') ? 0 : (6000 * enhancement_proficiency_modifier() )" ] }, + "base_energy_cost": { "math": [ "u_has_trait('EARTHSHAPER_STONE_SLEEP') ? 0 : (800 * enhancement_proficiency_modifier() )" ] } }, { "type": "effect_on_condition", @@ -1245,7 +1225,7 @@ "description": "While holding an item made of natural metal or stone, mold it with your hands, work to repairing any flaws and restoring its condition. Note that some items may still not be repaired.", "valid_targets": [ "self" ], "spell_class": "EARTHSHAPER", - "flags": [ "CONCENTRATE", "VERBAL", "NO_HANDS" ], + "flags": [ "CHANNELING_SPELL", "CONCENTRATE", "VERBAL", "NO_HANDS" ], "effect": "effect_on_condition", "effect_str": "EOC_EARTHSHAPER_REPAIR_METAL_STONE", "components": "spell_components_repair_metal_stone", @@ -1254,10 +1234,10 @@ "difficulty": 4, "max_level": 20, "energy_source": "MANA", - "base_energy_cost": { "math": [ "channeling_proficiency_negate_calculate(600, 5)" ] }, - "base_casting_time": { "math": [ "channeling_proficiency_negate_calculate(360000, 400)" ] }, - "final_casting_time": { "math": [ "channeling_proficiency_negate_calculate(90000, 400)" ] }, - "casting_time_increment": { "math": [ "channeling_proficiency_negate_calculate(-13500, 0.05)" ] } + "base_energy_cost": 600, + "base_casting_time": 360000, + "final_casting_time": 90000, + "casting_time_increment": -13500 }, { "type": "effect_on_condition", @@ -1282,7 +1262,11 @@ "condition": { "not": { "npc_has_flag": "NO_REPAIR" } }, "effect": [ { - "math": [ "n_hp('ALL')", "+=", "n_hp_max('bp_null') * ( (u_spell_level('earthshaper_repair_metal_stone') * 0.03) + 0.1)" ] + "math": [ + "n_hp('ALL')", + "+=", + "n_hp_max('bp_null') * ( (u_spell_level('earthshaper_repair_metal_stone') * 0.03) + 0.1) * channeling_proficiency_modifier()" + ] } ], "false_effect": [ diff --git a/data/mods/Magiclysm/eoc_spell_casting_proficiencies.json b/data/mods/Magiclysm/eoc_spell_casting_proficiencies.json index 80b1290a59923..bb752cc2aeacb 100644 --- a/data/mods/Magiclysm/eoc_spell_casting_proficiencies.json +++ b/data/mods/Magiclysm/eoc_spell_casting_proficiencies.json @@ -227,6 +227,82 @@ } ] }, + { + "type": "effect_on_condition", + "id": "EOC_SPELLCASTING_RESTORATION_PROFICIENCY_ADD", + "global": false, + "eoc_type": "ACTIVATION", + "effect": [ + { "math": [ "u_prof_lowest", "=", "4" ] }, + { + "if": { "math": [ "u_proficiency('prof_magic_restoration_beginner', 'format': 'percent')", ">=", "100" ] }, + "then": [ + { + "if": { "math": [ "u_proficiency('prof_magic_restoration_apprentice', 'format': 'percent')", ">=", "100" ] }, + "then": [ + { + "if": { "math": [ "u_proficiency('prof_magic_restoration_master', 'format': 'percent')", ">=", "100" ] }, + "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], + "else": [ + { "math": [ "u_proficiency('prof_magic_restoration_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, + { "math": [ "u_prof_level", "=", "2" ] }, + { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } + ] + } + ], + "else": [ + { "math": [ "u_proficiency('prof_magic_restoration_apprentice', 'format': 'percent')", "+=", "rand(4) / 32" ] }, + { "math": [ "u_prof_level", "=", "1" ] }, + { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } + ] + } + ], + "else": [ + { "math": [ "u_proficiency('prof_magic_restoration_beginner', 'format': 'percent')", "+=", "rand(4) / 16" ] }, + { "math": [ "u_prof_level", "=", "0" ] }, + { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } + ] + } + ] + }, + { + "type": "effect_on_condition", + "id": "EOC_SPELLCASTING_TRANSFORMATION_PROFICIENCY_ADD", + "global": false, + "eoc_type": "ACTIVATION", + "effect": [ + { "math": [ "u_prof_lowest", "=", "4" ] }, + { + "if": { "math": [ "u_proficiency('prof_magic_transformation_beginner', 'format': 'percent')", ">=", "100" ] }, + "then": [ + { + "if": { "math": [ "u_proficiency('prof_magic_transformation_apprentice', 'format': 'percent')", ">=", "100" ] }, + "then": [ + { + "if": { "math": [ "u_proficiency('prof_magic_transformation_master', 'format': 'percent')", ">=", "100" ] }, + "then": [ { "math": [ "u_prof_level", "=", "3" ] }, { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } ], + "else": [ + { "math": [ "u_proficiency('prof_magic_transformation_master', 'format': 'percent')", "+=", "rand(4) / 64" ] }, + { "math": [ "u_prof_level", "=", "2" ] }, + { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } + ] + } + ], + "else": [ + { "math": [ "u_proficiency('prof_magic_transformation_apprentice', 'format': 'percent')", "+=", "rand(4) / 32" ] }, + { "math": [ "u_prof_level", "=", "1" ] }, + { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } + ] + } + ], + "else": [ + { "math": [ "u_proficiency('prof_magic_transformation_beginner', 'format': 'percent')", "+=", "rand(4) / 16" ] }, + { "math": [ "u_prof_level", "=", "0" ] }, + { "math": [ "u_prof_lowest", "=", "min(u_prof_level, u_prof_lowest)" ] } + ] + } + ] + }, { "type": "effect_on_condition", "id": "EOC_EVOCATION_SPELLS_PROFICIENCY_BONUSES", @@ -351,5 +427,49 @@ ] } ] + }, + { + "type": "effect_on_condition", + "id": "EOC_RESTORATION_SPELLS_PROFICIENCY_BONUSES", + "eoc_type": "EVENT", + "required_event": "opens_spellbook", + "effect": [ + { + "math": [ + "u_spellcasting_adjustment('damage', 'flag_whitelist': 'RESTORATION_SPELL')", + "=", + "( (u_proficiency('prof_magic_restoration_beginner', 'format': 'percent') / 1000) + (u_proficiency('prof_magic_restoration_apprentice', 'format': 'percent') / 1000) + (u_proficiency('prof_magic_restoration_master', 'format': 'percent') / 1000) )" + ] + }, + { + "math": [ + "u_spellcasting_adjustment('casting_time', 'flag_whitelist': 'RESTORATION_SPELL')", + "=", + "( (u_proficiency('prof_magic_restoration_beginner', 'format': 'percent') / 1000) + (u_proficiency('prof_magic_restoration_apprentice', 'format': 'percent') / 1000) + (u_proficiency('prof_magic_restoration_master', 'format': 'percent') / 1000) ) * -1" + ] + } + ] + }, + { + "type": "effect_on_condition", + "id": "EOC_TRANSFORMATION_SPELLS_PROFICIENCY_BONUSES", + "eoc_type": "EVENT", + "required_event": "opens_spellbook", + "effect": [ + { + "math": [ + "u_spellcasting_adjustment('casting_time', 'flag_whitelist': 'TRANSFORMATION_SPELL')", + "=", + "( (u_proficiency('prof_magic_transformation_beginner', 'format': 'percent') / 1000) + (u_proficiency('prof_magic_transformation_apprentice', 'format': 'percent') / 1000) + (u_proficiency('prof_magic_transformation_master', 'format': 'percent') / 1000) ) * -1" + ] + }, + { + "math": [ + "u_spellcasting_adjustment('duration', 'flag_whitelist': 'TRANSFORMATION_SPELL')", + "=", + "( (u_proficiency('prof_magic_transformation_beginner', 'format': 'percent') / 1000) + (u_proficiency('prof_magic_transformation_apprentice', 'format': 'percent') / 1000) + (u_proficiency('prof_magic_transformation_master', 'format': 'percent') / 1000) )" + ] + } + ] } ] diff --git a/data/mods/Magiclysm/jmath.json b/data/mods/Magiclysm/jmath.json index 398d6d0b3b0d9..68fc8f6722d7c 100644 --- a/data/mods/Magiclysm/jmath.json +++ b/data/mods/Magiclysm/jmath.json @@ -11,6 +11,12 @@ "num_args": 2, "return": "_0 - ((((u_proficiency('prof_magic_evocation_beginner', 'format': 'percent') * 1) / 10) + ((u_proficiency('prof_magic_evocation_apprentice', 'format': 'percent') * 1) / 10) + ((u_proficiency('prof_magic_evocation_master', 'format': 'percent') * 1) / 10)) * _1 )" }, + { + "type": "jmath_function", + "id": "evocation_proficiency_modifier", + "num_args": 0, + "return": "1 + ( (u_proficiency('prof_magic_evocation_beginner', 'format': 'percent') / 1000) + (u_proficiency('prof_magic_evocation_apprentice', 'format': 'percent') / 1000) + (u_proficiency('prof_magic_evocation_master', 'format': 'percent') / 1000) )" + }, { "type": "jmath_function", "id": "channeling_proficiency_negate_calculate", @@ -23,6 +29,12 @@ "num_args": 2, "return": "_0 + (((((u_proficiency('prof_magic_channel_beginner', 'format': 'percent') * 1) / 10) + ((u_proficiency('prof_magic_channel_apprentice', 'format': 'percent') * 1) / 10) + ((u_proficiency('prof_magic_channel_master', 'format': 'percent') * 1) / 10))) * _1 )" }, + { + "type": "jmath_function", + "id": "channeling_proficiency_modifier", + "num_args": 0, + "return": "1 + ( (u_proficiency('prof_magic_channel_beginner', 'format': 'percent') / 1000) + (u_proficiency('prof_magic_channel_apprentice', 'format': 'percent') / 1000) + (u_proficiency('prof_magic_channel_master', 'format': 'percent') / 1000) )" + }, { "type": "jmath_function", "id": "summoning_proficiency_bonus_calculate", @@ -71,5 +83,17 @@ "id": "conveyance_proficiency_negate_calculate", "num_args": 2, "return": "_0 - (((((u_proficiency('prof_magic_conveyance_beginner', 'format': 'percent') * 1) / 10) + ((u_proficiency('prof_magic_conveyance_apprentice', 'format': 'percent') * 1) / 10) + ((u_proficiency('prof_magic_conveyance_master', 'format': 'percent') * 1) / 10))) * _1 )" + }, + { + "type": "jmath_function", + "id": "restoration_proficiency_modifier", + "num_args": 0, + "return": "1 + ( (u_proficiency('prof_magic_restoration_beginner', 'format': 'percent') / 1000) + (u_proficiency('prof_magic_restoration_apprentice', 'format': 'percent') / 1000) + (u_proficiency('prof_magic_restoration_master', 'format': 'percent') / 1000) )" + }, + { + "type": "jmath_function", + "id": "transformation_proficiency_modifier", + "num_args": 0, + "return": "1 + ( (u_proficiency('prof_magic_transformation_beginner', 'format': 'percent') / 1000) + (u_proficiency('prof_magic_transformation_apprentice', 'format': 'percent') / 1000) + (u_proficiency('prof_magic_transformation_master', 'format': 'percent') / 1000) )" } ] diff --git a/data/mods/Magiclysm/magic_balance.md b/data/mods/Magiclysm/magic_balance.md index 626f93bff79ef..0dba2f6b15f1b 100644 --- a/data/mods/Magiclysm/magic_balance.md +++ b/data/mods/Magiclysm/magic_balance.md @@ -105,6 +105,12 @@ Enervation spells are the opposite of Enhancement, being spells that reduce the ### Conveyance Conveyance encompasses spells which involve translocating, teleporting, or moving the caster/target. Some spells covered are Phase Door, Magus's Mark, Shocking Dash, or Translocate Self. Proficiency in Conveyance will extend the range of the spell and lower the mana cost of the incantation. +## Restoration +Restoration spells return the physical, spiritually, emotional, or magical capabilities of the target to its ideal state. Spells like Cure Light Wounds, Sacrificial Regrowth, Mind over Pain, or Stone's Endurance are all restoration spells. Proficiency in Restoration will reduce the casting time and increase the amount healed. + +## Transformation +Transformation spells change one thing into another, such as changing a handful of leaves into gold or changing a charging enemy into a housecat. This also includes partial tranformations of the target. Spells like Harvest of the Hunter, Vicious Tentacle, or Convert are transformation spells. Proficiency in Transformation will increase the duration and reduce the casting time. + #### How The JMATH Works The JMATH behind spellcasting proficiencies is fairly simple, this is how it works: diff --git a/data/mods/Magiclysm/proficiencies.json b/data/mods/Magiclysm/proficiencies.json index 454599881fd96..c890da6198b66 100644 --- a/data/mods/Magiclysm/proficiencies.json +++ b/data/mods/Magiclysm/proficiencies.json @@ -306,5 +306,77 @@ "default_skill_penalty": 0.2, "time_to_learn": "32 h", "required_proficiencies": [ "prof_magic_conveyance_apprentice" ] + }, + { + "type": "proficiency", + "id": "prof_magic_restoration_beginner", + "category": "prof_magic_casting", + "name": { "str": "Novice Restoration" }, + "//": "This covers anything that restores the base physical, spiritual, or mental capabilities of the target, like healing spells.", + "description": "You're familiar with how to return a target to its normal condition.", + "can_learn": true, + "default_time_multiplier": 1.5, + "default_skill_penalty": 0.2, + "time_to_learn": "8 h" + }, + { + "type": "proficiency", + "id": "prof_magic_restoration_apprentice", + "category": "prof_magic_casting", + "name": { "str": "Apprentice Restoration" }, + "description": "You're proficient in returning a target to its base condition, curing any ills it might suffer.", + "can_learn": true, + "default_time_multiplier": 1.5, + "default_skill_penalty": 0.2, + "time_to_learn": "16 h", + "required_proficiencies": [ "prof_magic_conveyance_beginner" ] + }, + { + "type": "proficiency", + "id": "prof_magic_restoration_master", + "category": "prof_magic_casting", + "name": { "str": "Master Restoration" }, + "description": "You've mastered the art of restoring a target to its normal condition.", + "can_learn": true, + "default_time_multiplier": 1.5, + "default_skill_penalty": 0.2, + "time_to_learn": "32 h", + "required_proficiencies": [ "prof_magic_conveyance_apprentice" ] + }, + { + "type": "proficiency", + "id": "prof_magic_transformation_beginner", + "category": "prof_magic_casting", + "name": { "str": "Novice Transformation" }, + "//": "This covers anything that turns one thing into another, like leaves into gold or a human into a bear. It also covers magical mutation.", + "description": "You're familiar with how to turn things into other things using magic.", + "can_learn": true, + "default_time_multiplier": 1.5, + "default_skill_penalty": 0.2, + "time_to_learn": "8 h" + }, + { + "type": "proficiency", + "id": "prof_magic_transformation_apprentice", + "category": "prof_magic_casting", + "name": { "str": "Apprentice Transformation" }, + "description": "You're proficient in turning things into other things using magic.", + "can_learn": true, + "default_time_multiplier": 1.5, + "default_skill_penalty": 0.2, + "time_to_learn": "16 h", + "required_proficiencies": [ "prof_magic_conveyance_beginner" ] + }, + { + "type": "proficiency", + "id": "prof_magic_transformation_master", + "category": "prof_magic_casting", + "name": { "str": "Master Transformation" }, + "description": "You've mastered the art of transforming the physical form of creatures and objects.", + "can_learn": true, + "default_time_multiplier": 1.5, + "default_skill_penalty": 0.2, + "time_to_learn": "32 h", + "required_proficiencies": [ "prof_magic_conveyance_apprentice" ] } ] diff --git a/src/magic.cpp b/src/magic.cpp index d600eb968a1df..c8762bfff9cd2 100644 --- a/src/magic.cpp +++ b/src/magic.cpp @@ -173,6 +173,8 @@ std::string enum_to_string( spell_flag data ) case spell_flag::ENHANCEMENT_SPELL: return "ENHANCEMENT_SPELL"; case spell_flag::ENERVATION_SPELL: return "ENERVATION_SPELL"; case spell_flag::CONVEYANCE_SPELL: return "CONVEYANCE_SPELL"; + case spell_flag::RESTORATION_SPELL: return "RESTORATION_SPELL"; + case spell_flag::TRANSFORMATION_SPELL: return "TRANSFORMATION_SPELL"; case spell_flag::LAST: break; } cata_fatal( "Invalid spell_flag" ); @@ -2526,6 +2528,12 @@ std::string spell::enumerate_spell_data( const Character &guy ) const if( has_flag( spell_flag::CONVEYANCE_SPELL ) ) { spell_data.emplace_back( _( "is a conveyance spell" ) ); } + if( has_flag( spell_flag::RESTORATION_SPELL ) ) { + spell_data.emplace_back( _( "is a restoration spell" ) ); + } + if( has_flag( spell_flag::TRANSFORMATION_SPELL ) ) { + spell_data.emplace_back( _( "is a transformation spell" ) ); + } if( has_flag( spell_flag::CONCENTRATE ) && !has_flag( spell_flag::PSIONIC ) && temp_concentration_difficulty_multiplyer > 0 ) { spell_data.emplace_back( _( "requires concentration" ) ); diff --git a/src/magic.h b/src/magic.h index c3e44f70faeed..df64f053b0bd9 100644 --- a/src/magic.h +++ b/src/magic.h @@ -91,6 +91,8 @@ enum class spell_flag : int { ENHANCEMENT_SPELL, // Enhancement spell category, used for Magiclysm proficiencies ENERVATION_SPELL, // Enervation spell category, used for Magiclysm proficiencies CONVEYANCE_SPELL, // Conveyance spell category, used for Magiclysm proficiencies + RESTORATION_SPELL, // Restoration spell category, used for Magiclysm proficiencies + TRANSFORMATION_SPELL, // Transformation spell category, used for Magiclysm proficiencies LAST }; From 57d1e416f1922a955d7c8f9c4b4264309c77c749 Mon Sep 17 00:00:00 2001 From: Karol1223 <68503002+Karol1223@users.noreply.github.com> Date: Fri, 6 Sep 2024 21:59:38 +0200 Subject: [PATCH 09/12] Move some IDs only used in mods to corresponding mod files, remove ``VERMIN`` flag (#76091) * ``necropolis_freq`` * MMAs * feral guns * Rat King death * ``VERMIN`` --- data/json/items/book/martial.json | 50 ------------- data/json/items/book/misc.json | 17 ----- .../monster_deaths.json | 14 ---- .../monster_special_attacks/monster_gun.json | 75 ------------------- data/json/monsters/monster_flags.json | 5 -- .../firearms/gg_firearms_migration.json | 15 ---- data/mods/Generic_Guns/firearms/pistol.json | 18 ----- data/mods/Generic_Guns/firearms/rifle.json | 9 --- data/mods/Generic_Guns/firearms/shot.json | 9 --- data/mods/MMA/martial.json | 45 +++++++++++ data/mods/No_Hope/items.json | 16 ++++ data/mods/TEST_DATA/item_demographics.json | 7 +- .../monster_special_attacks.json | 14 ++++ doc/JSON_FLAGS.md | 1 - src/creature_tracker.cpp | 5 -- src/mtype.cpp | 2 - src/mtype.h | 1 - 17 files changed, 77 insertions(+), 226 deletions(-) diff --git a/data/json/items/book/martial.json b/data/json/items/book/martial.json index caae4c5a4f2be..35e91417c78fd 100644 --- a/data/json/items/book/martial.json +++ b/data/json/items/book/martial.json @@ -43,16 +43,6 @@ "description": "A complete guide to Capoeira.", "martial_art": "style_capoeira" }, - { - "id": "manual_centipede", - "copy-from": "book_martial", - "type": "BOOK", - "name": { "str": "The Centipede Lu Feng", "str_pl": "copies of The Centipede Lu Feng" }, - "//": "Could be moved to Mythical Martial Arts mod after 0.G.", - "price_postapoc": "20 USD", - "description": "A complete guide to Centipede Kung Fu.", - "martial_art": "style_centipede" - }, { "id": "manual_crane", "copy-from": "book_martial", @@ -143,16 +133,6 @@ "description": "A complete guide to Leopard Kung Fu.", "martial_art": "style_leopard" }, - { - "id": "manual_lizard", - "copy-from": "book_martial", - "type": "BOOK", - "name": { "str": "The Lizard Kuo Chui", "str_pl": "copies of The Lizard Kuo Chui" }, - "//": "Could be moved to Mythical Martial Arts mod after 0.G.", - "price_postapoc": "20 USD", - "description": "A complete guide to Lizard Kung Fu.", - "martial_art": "style_lizard" - }, { "id": "manual_muay_thai", "copy-from": "book_martial", @@ -189,16 +169,6 @@ "description": "A complete guide to Pankration.", "martial_art": "style_pankration" }, - { - "id": "manual_scorpion", - "copy-from": "book_martial", - "type": "BOOK", - "name": { "str": "The Scorpion Sun Chien", "str_pl": "copies of The Scorpion Sun Chien" }, - "//": "Could be moved to Mythical Martial Arts mod after 0.G.", - "price_postapoc": "20 USD", - "description": "A complete guide to Scorpion Kung Fu.", - "martial_art": "style_scorpion" - }, { "id": "manual_silat", "copy-from": "book_martial", @@ -244,26 +214,6 @@ "description": "A complete guide to Tiger Kung Fu.", "martial_art": "style_tiger" }, - { - "id": "manual_toad", - "copy-from": "book_martial", - "type": "BOOK", - "name": { "str": "The Toad Lo Mang", "str_pl": "copies of The Toad Lo Mang" }, - "//": "Could be moved to Mythical Martial Arts mod after 0.G.", - "price_postapoc": "20 USD", - "description": "A complete guide to Toad Kung Fu.", - "martial_art": "style_toad" - }, - { - "id": "manual_venom_snake", - "copy-from": "book_martial", - "type": "BOOK", - "name": { "str": "The Viper Wei Pai", "str_pl": "copies of The Viper Wei Pai" }, - "//": "Could be moved to Mythical Martial Arts mod after 0.G.", - "price_postapoc": "20 USD", - "description": "A complete guide to Viper Kung Fu.", - "martial_art": "style_venom_snake" - }, { "id": "manual_zui_quan", "copy-from": "book_martial", diff --git a/data/json/items/book/misc.json b/data/json/items/book/misc.json index eca91699973f7..1e2410a38df99 100644 --- a/data/json/items/book/misc.json +++ b/data/json/items/book/misc.json @@ -172,23 +172,6 @@ "chapters": 4, "fun": 1 }, - { - "id": "necropolis_freq", - "type": "BOOK", - "name": { "str": "frequency list" }, - "description": "A notepad with a number of frequencies scribbled on it.", - "weight": "1 g", - "volume": "250 ml", - "price": "30 USD", - "price_postapoc": "50 cent", - "material": [ "paper" ], - "symbol": "?", - "looks_like": "pocket_firstaid", - "color": "light_cyan", - "intelligence": 2, - "time": "10 m", - "melee_damage": { "bash": 1 } - }, { "id": "news_regional", "type": "BOOK", diff --git a/data/json/monster_special_attacks/monster_deaths.json b/data/json/monster_special_attacks/monster_deaths.json index b51fb03c53386..840337084773e 100644 --- a/data/json/monster_special_attacks/monster_deaths.json +++ b/data/json/monster_special_attacks/monster_deaths.json @@ -595,20 +595,6 @@ "min_aoe": 3, "max_aoe": 3 }, - { - "id": "death_ratking", - "type": "SPELL", - "name": { "str": "Rat King Death" }, - "description": "Rat king dies.", - "valid_targets": [ "hostile", "ally" ], - "shape": "blast", - "flags": [ "NO_EXPLOSION_SFX" ], - "effect": "remove_effect", - "effect_str": "rat", - "min_range": 48, - "max_range": 48, - "extra_effects": [ { "id": "ratking_summon_rats", "hit_self": true } ] - }, { "id": "death_focused_beam_explosion", "type": "SPELL", diff --git a/data/json/monster_special_attacks/monster_gun.json b/data/json/monster_special_attacks/monster_gun.json index bb0f91cbf44a3..d0c5ce823f762 100644 --- a/data/json/monster_special_attacks/monster_gun.json +++ b/data/json/monster_special_attacks/monster_gun.json @@ -194,81 +194,6 @@ "ranged_damage": { "damage_type": "electric", "amount": 10, "armor_penetration": 4 }, "flags": [ "PSEUDO", "NEVER_JAMS", "NO_UNLOAD", "NON_FOULING", "NEEDS_NO_LUBE", "NO_TURRET" ] }, - { - "id": "feral_militia_gun", - "type": "GUN", - "symbol": "R", - "color": "dark_gray", - "name": { "str": "mad militias' rifle" }, - "description": "A fake semi-auto rifle for feral militiamen (because monster aiming is too lethal).", - "material": [ "steel", "plastic" ], - "skill": "rifle", - "flags": [ "PSEUDO", "NONCONDUCTIVE", "NO_REPAIR", "NO_SALVAGE", "NO_UNLOAD", "RELOAD_AND_SHOOT" ], - "ammo": [ "223" ], - "clip_size": 30, - "longest_side": "83200 cm", - "weight": "5000 g", - "volume": "2000 ml", - "dispersion": 3000, - "range": 100, - "durability": 8, - "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "223": 1 } } ], - "melee_damage": { "bash": 3 } - }, - { - "id": "feral_jackboot_gun", - "type": "GUN", - "symbol": "R", - "color": "dark_gray", - "name": { "str": "feral bikers' shotgun" }, - "description": "A fake shotgun for feral bikers (because monster aiming is too lethal).", - "material": [ "steel", "aluminum", "plastic" ], - "skill": "shotgun", - "flags": [ "PSEUDO", "NONCONDUCTIVE", "NO_REPAIR", "NO_SALVAGE", "NO_UNLOAD", "RELOAD_AND_SHOOT" ], - "ammo": [ "shot" ], - "clip_size": 6, - "longest_side": "1166 cm", - "weight": "3402 g", - "volume": "2450 ml", - "dispersion": 3250, - "range": 65, - "durability": 9, - "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "shot": 1 } } ], - "melee_damage": { "bash": 3 } - }, - { - "id": "feral_m9", - "copy-from": "pistol_base", - "looks_like": "glock_17", - "type": "GUN", - "name": { "str_sp": "Beretta M9A1" }, - "description": "A poorly maintained and inaccurate version of the M9 for feral security guards, feral preppers, etc.", - "ascii_picture": "beretta_m9", - "weight": "961 g", - "volume": "570 ml", - "flags": [ "PSEUDO" ], - "longest_side": "249 mm", - "price": "650 USD", - "price_postapoc": "25 USD", - "ranged_damage": { "damage_type": "bullet", "amount": -4 }, - "material": [ "steel", "aluminum" ], - "symbol": "(", - "color": "dark_gray", - "ammo": [ "9mm" ], - "range": 1, - "dispersion": 4800, - "durability": 7, - "min_cycle_recoil": 450, - "weapon_category": [ "AUTOMATIC_PISTOLS" ], - "pocket_data": [ - { - "magazine_well": "250 ml", - "pocket_type": "MAGAZINE_WELL", - "item_restriction": [ "m9mag", "m9mag_10rd", "m9mag_17rd", "m9mag_18rd", "m9mag_20rd", "m9bigmag", "m9mag_32rd", "m9mag_35rd" ] - } - ], - "melee_damage": { "bash": 8 } - }, { "id": "civilian_cop_glock22", "copy-from": "glock_22", diff --git a/data/json/monsters/monster_flags.json b/data/json/monsters/monster_flags.json index 7f2374e55e501..b287716301731 100644 --- a/data/json/monsters/monster_flags.json +++ b/data/json/monsters/monster_flags.json @@ -309,11 +309,6 @@ "type": "monster_flag", "//": "Monster dies quietly and doesn't display a message." }, - { - "id": "VERMIN", - "type": "monster_flag", - "//": "Obsolete flag labeling \"nuisance\" or \"scenery\" monsters, now used to prevent loading the same" - }, { "id": "NOGIB", "type": "monster_flag", diff --git a/data/mods/Generic_Guns/firearms/gg_firearms_migration.json b/data/mods/Generic_Guns/firearms/gg_firearms_migration.json index 402b0540fa9e1..79acfb5986479 100644 --- a/data/mods/Generic_Guns/firearms/gg_firearms_migration.json +++ b/data/mods/Generic_Guns/firearms/gg_firearms_migration.json @@ -477,20 +477,5 @@ "id": [ "m26_mass_standalone" ], "type": "MIGRATION", "replace": "small_shotgun" - }, - { - "id": [ "feral_militia_gun" ], - "type": "MIGRATION", - "replace": "feral_rifle" - }, - { - "id": [ "feral_jackboot_gun" ], - "type": "MIGRATION", - "replace": "feral_shotgun" - }, - { - "id": [ "feral_m9" ], - "type": "MIGRATION", - "replace": "feral_pistol" } ] diff --git a/data/mods/Generic_Guns/firearms/pistol.json b/data/mods/Generic_Guns/firearms/pistol.json index 8355af762aaeb..f7eb3ab1f5087 100644 --- a/data/mods/Generic_Guns/firearms/pistol.json +++ b/data/mods/Generic_Guns/firearms/pistol.json @@ -110,23 +110,5 @@ "rigid": true } ] - }, - { - "id": "feral_pistol", - "copy-from": "feral_m9", - "type": "GUN", - "name": { "str_sp": "Beretta M9A1" }, - "description": "A poorly maintained and inaccurate version of the M9 for feral security guards, feral preppers, etc.", - "ammo": [ "ammo_pistol" ], - "pocket_data": [ - { - "pocket_type": "MAGAZINE_WELL", - "holster": true, - "max_contains_volume": "20 L", - "max_contains_weight": "20 kg", - "item_restriction": [ "pistol_mag", "pistol_smg_mag" ], - "rigid": true - } - ] } ] diff --git a/data/mods/Generic_Guns/firearms/rifle.json b/data/mods/Generic_Guns/firearms/rifle.json index d1cbecdcbf084..80ef35b8a6516 100644 --- a/data/mods/Generic_Guns/firearms/rifle.json +++ b/data/mods/Generic_Guns/firearms/rifle.json @@ -131,14 +131,5 @@ "description": "A break action firearm comprised of a rifle barrel over two smooth bore shotgun barrels. Historically used by egomaniac hunters in Africa, now used by their egomaniac descendants in New England.", "built_in_mods": [ "rifle_shotgun_combination_shotgun" ], "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "ammo_rifle": 1 } } ] - }, - { - "id": "feral_rifle", - "copy-from": "feral_militia_gun", - "type": "GUN", - "name": { "str": "mad militias' rifle" }, - "description": "A fake semi-auto rifle for feral militiamen (because monster aiming is too lethal).", - "ammo": [ "ammo_rifle" ], - "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "ammo_rifle": 1 } } ] } ] diff --git a/data/mods/Generic_Guns/firearms/shot.json b/data/mods/Generic_Guns/firearms/shot.json index f1223bbb40b52..5a3aeb1d62e71 100644 --- a/data/mods/Generic_Guns/firearms/shot.json +++ b/data/mods/Generic_Guns/firearms/shot.json @@ -84,14 +84,5 @@ "name": { "str": "compact shotgun" }, "description": "Small shotgun, assembled from underbarrel shotgun modification and a pistol grip. Not the best weapon, but has a really small size and weight.", "ammo": [ "ammo_shot" ] - }, - { - "id": "feral_shotgun", - "copy-from": "feral_jackboot_gun", - "type": "GUN", - "name": { "str": "feral bikers' shotgun" }, - "description": "A fake shotgun for feral bikers (because monster aiming is too lethal).", - "ammo": [ "ammo_shot" ], - "pocket_data": [ { "pocket_type": "MAGAZINE", "ammo_restriction": { "ammo_shot": 1 }, "rigid": true } ] } ] diff --git a/data/mods/MMA/martial.json b/data/mods/MMA/martial.json index 0a1cc1828e796..d16fe28a93d9b 100644 --- a/data/mods/MMA/martial.json +++ b/data/mods/MMA/martial.json @@ -117,5 +117,50 @@ "type": "transform" }, "countdown_action": { "type": "cast_spell", "spell_id": "learn_ki_strike", "no_fail": true, "level": 0 } + }, + { + "id": "manual_centipede", + "copy-from": "book_martial", + "type": "BOOK", + "name": { "str": "The Centipede Lu Feng", "str_pl": "copies of The Centipede Lu Feng" }, + "price_postapoc": "20 USD", + "description": "A complete guide to Centipede Kung Fu.", + "martial_art": "style_centipede" + }, + { + "id": "manual_lizard", + "copy-from": "book_martial", + "type": "BOOK", + "name": { "str": "The Lizard Kuo Chui", "str_pl": "copies of The Lizard Kuo Chui" }, + "price_postapoc": "20 USD", + "description": "A complete guide to Lizard Kung Fu.", + "martial_art": "style_lizard" + }, + { + "id": "manual_scorpion", + "copy-from": "book_martial", + "type": "BOOK", + "name": { "str": "The Scorpion Sun Chien", "str_pl": "copies of The Scorpion Sun Chien" }, + "price_postapoc": "20 USD", + "description": "A complete guide to Scorpion Kung Fu.", + "martial_art": "style_scorpion" + }, + { + "id": "manual_toad", + "copy-from": "book_martial", + "type": "BOOK", + "name": { "str": "The Toad Lo Mang", "str_pl": "copies of The Toad Lo Mang" }, + "price_postapoc": "20 USD", + "description": "A complete guide to Toad Kung Fu.", + "martial_art": "style_toad" + }, + { + "id": "manual_venom_snake", + "copy-from": "book_martial", + "type": "BOOK", + "name": { "str": "The Viper Wei Pai", "str_pl": "copies of The Viper Wei Pai" }, + "price_postapoc": "20 USD", + "description": "A complete guide to Viper Kung Fu.", + "martial_art": "style_venom_snake" } ] diff --git a/data/mods/No_Hope/items.json b/data/mods/No_Hope/items.json index c5948094afc9b..519894655d789 100644 --- a/data/mods/No_Hope/items.json +++ b/data/mods/No_Hope/items.json @@ -312,5 +312,21 @@ "material": [ "paper" ], "weight": "1 g", "volume": "1 ml" + }, + { + "id": "necropolis_freq", + "type": "BOOK", + "name": { "str": "frequency list" }, + "description": "A notepad with a number of frequencies scribbled on it.", + "weight": "200 g", + "volume": "250 ml", + "price": "30 USD", + "price_postapoc": "50 cent", + "material": [ "paper" ], + "symbol": "?", + "looks_like": "pocket_firstaid", + "color": "light_cyan", + "intelligence": 2, + "time": "10 m" } ] diff --git a/data/mods/TEST_DATA/item_demographics.json b/data/mods/TEST_DATA/item_demographics.json index f911649093f6f..0550fbb50f147 100644 --- a/data/mods/TEST_DATA/item_demographics.json +++ b/data/mods/TEST_DATA/item_demographics.json @@ -682,8 +682,7 @@ "colt_ro635": 1, "bt_apc9k": 1, "calico": 1, - "cx4": 1, - "feral_m9": 1 + "cx4": 1 } }, { @@ -728,8 +727,7 @@ "ak556": 1, "minidraco556": 1, "bren2_556": 1, - "rdb_223": 1, - "feral_militia_gun": 1 + "rdb_223": 1 } }, { @@ -986,7 +984,6 @@ "draco_micro": 1, "draco_mini": 1, "emp_frond": 1, - "feral_m9": 1, "fn1910": 1, "fn57": 1, "glock_17": 1, diff --git a/data/mods/Xedra_Evolved/monster_special_attacks/monster_special_attacks.json b/data/mods/Xedra_Evolved/monster_special_attacks/monster_special_attacks.json index 3c5281f1fd37b..6b6dfe88eaff5 100644 --- a/data/mods/Xedra_Evolved/monster_special_attacks/monster_special_attacks.json +++ b/data/mods/Xedra_Evolved/monster_special_attacks/monster_special_attacks.json @@ -90,5 +90,19 @@ "miss_msg_u": "%1$s tries to curse your %2$s but you dodge!", "miss_msg_npc": "%s tries to curse and knock down , but they dodge!", "effects": [ { "id": "downed", "duration": 3 }, { "id": "stunned", "duration": 100 } ] + }, + { + "id": "death_ratking", + "type": "SPELL", + "name": { "str": "Rat King Death" }, + "description": "Rat king dies.", + "valid_targets": [ "hostile", "ally" ], + "shape": "blast", + "flags": [ "NO_EXPLOSION_SFX" ], + "effect": "remove_effect", + "effect_str": "rat", + "min_range": 48, + "max_range": 48, + "extra_effects": [ { "id": "ratking_summon_rats", "hit_self": true } ] } ] diff --git a/doc/JSON_FLAGS.md b/doc/JSON_FLAGS.md index 503bc30ddac6d..721a508f1aa22 100644 --- a/doc/JSON_FLAGS.md +++ b/doc/JSON_FLAGS.md @@ -1185,7 +1185,6 @@ Used to describe monster characteristics and set their properties and abilities. - ```SWIMS``` Treats water as 50 movement point terrain. - ```VAMP_VIRUS``` This monster can inflict the `vampire_virus` effect. Used by Xedra Evolved mod. - ```VENOM``` Attack may poison the player. -- ```VERMIN``` Obsolete flag for inconsequential monsters, now prevents loading. - ```WARM``` Warm blooded. - ```WATER_CAMOUFLAGE``` If in water, stays invisible up to (current Perception, + base Perception if the character has the Spotting proficiency) tiles away, even in broad daylight. Monsters see it from the lower of `vision_day` and `vision_night` ranges. Can also make it harder to see in deep water or across z-levels if it is underwater and the viewer is not. - ```WEBWALK``` Doesn't destroy webs and won't get caught in them. diff --git a/src/creature_tracker.cpp b/src/creature_tracker.cpp index f9224a1f50c2f..f8a8950aacf97 100644 --- a/src/creature_tracker.cpp +++ b/src/creature_tracker.cpp @@ -74,11 +74,6 @@ bool creature_tracker::add( const shared_ptr_fast &critter_ptr ) return false; } - if( critter.type->has_flag( mon_flag_VERMIN ) ) { - // Don't spawn vermin, they aren't implemented yet - return false; - } - if( const shared_ptr_fast existing_mon_ptr = find( critter.get_location() ) ) { // We can spawn stuff on hallucinations, but we need to kill them first if( existing_mon_ptr->is_hallucination() ) { diff --git a/src/mtype.cpp b/src/mtype.cpp index 3464bb37ccedb..9ef8915c91464 100644 --- a/src/mtype.cpp +++ b/src/mtype.cpp @@ -155,7 +155,6 @@ mon_flag_id mon_flag_ACIDPROOF, mon_flag_SWIMS, mon_flag_VAMP_VIRUS, mon_flag_VENOM, - mon_flag_VERMIN, mon_flag_WARM, mon_flag_WATER_CAMOUFLAGE, mon_flag_WEBWALK, @@ -278,7 +277,6 @@ void set_mon_flag_ids() mon_flag_SWIMS = mon_flag_id( "SWIMS" ); mon_flag_VAMP_VIRUS = mon_flag_id( "VAMP_VIRUS" ); mon_flag_VENOM = mon_flag_id( "VENOM" ); - mon_flag_VERMIN = mon_flag_id( "VERMIN" ); mon_flag_WARM = mon_flag_id( "WARM" ); mon_flag_WATER_CAMOUFLAGE = mon_flag_id( "WATER_CAMOUFLAGE" ); mon_flag_WEBWALK = mon_flag_id( "WEBWALK" ); diff --git a/src/mtype.h b/src/mtype.h index 61bb9c1aa70e8..340748ccae7b0 100644 --- a/src/mtype.h +++ b/src/mtype.h @@ -195,7 +195,6 @@ extern mon_flag_id mon_flag_ACIDPROOF, mon_flag_SWIMS, mon_flag_VAMP_VIRUS, mon_flag_VENOM, - mon_flag_VERMIN, mon_flag_WARM, mon_flag_WATER_CAMOUFLAGE, mon_flag_WEBWALK, From b55d6af6300dfce8299c1a1d902b491dbad1101d Mon Sep 17 00:00:00 2001 From: Karol1223 <68503002+Karol1223@users.noreply.github.com> Date: Fri, 6 Sep 2024 22:02:03 +0200 Subject: [PATCH 10/12] Clean up some vanilla-unused itemgroups (#76086) * defense mode file * jackson drops * shia * vault wanderer * feral diver + weird daycare * Update item_groups.json --- .../Drugs_Tobacco_Alcohol/drugs.json | 24 ++++++++++ .../Drugs_Tobacco_Alcohol/tobacco.json | 8 ++++ data/json/itemgroups/Food/food.json | 8 ++++ .../locations_commercial.json | 13 ------ .../monster_drops_lairs.json | 44 ------------------- data/json/monsterdrops/feral_humans.json | 24 ---------- data/json/monsterdrops/misc.json | 12 ----- .../CrazyCataclysm/crazy_item_groups.json | 18 ++++++++ .../Defense_Mode/itemgroups.json} | 40 ----------------- data/mods/No_Hope/item_groups.json | 38 ++++++++++++++++ 10 files changed, 96 insertions(+), 133 deletions(-) rename data/{json/itemgroups/defense_mode.json => mods/Defense_Mode/itemgroups.json} (70%) diff --git a/data/json/itemgroups/Drugs_Tobacco_Alcohol/drugs.json b/data/json/itemgroups/Drugs_Tobacco_Alcohol/drugs.json index 891fa678f3c1c..8d1eea56d276b 100644 --- a/data/json/itemgroups/Drugs_Tobacco_Alcohol/drugs.json +++ b/data/json/itemgroups/Drugs_Tobacco_Alcohol/drugs.json @@ -820,5 +820,29 @@ "id": "pillbox_any_used", "subtype": "distribution", "groups": [ "pillbox_used", "pillbox_large_used" ] + }, + { + "type": "item_group", + "id": "codeine_bottle_plastic_pill_painkiller_10", + "subtype": "collection", + "//": "This group was created automatically and may contain errors.", + "container-item": "bottle_plastic_pill_painkiller", + "entries": [ { "item": "codeine", "container-item": "null", "count": 10 } ] + }, + { + "type": "item_group", + "id": "oxycodone_bottle_plastic_pill_prescription_10", + "subtype": "collection", + "//": "This group was created automatically and may contain errors.", + "container-item": "bottle_plastic_pill_prescription", + "entries": [ { "item": "oxycodone", "container-item": "null", "count": 10 } ] + }, + { + "type": "item_group", + "id": "meth_bag_zipper_6", + "subtype": "collection", + "//": "This group was created automatically and may contain errors.", + "container-item": "bag_zipper", + "entries": [ { "item": "meth", "container-item": "null", "count": 6 } ] } ] diff --git a/data/json/itemgroups/Drugs_Tobacco_Alcohol/tobacco.json b/data/json/itemgroups/Drugs_Tobacco_Alcohol/tobacco.json index 1434bfbf9c80d..99c7bf0001f74 100644 --- a/data/json/itemgroups/Drugs_Tobacco_Alcohol/tobacco.json +++ b/data/json/itemgroups/Drugs_Tobacco_Alcohol/tobacco.json @@ -84,5 +84,13 @@ "//": "This group was created automatically and may contain errors.", "container-item": "wrapper", "entries": [ { "item": "chaw", "container-item": "null", "count": [ 1, 20 ] } ] + }, + { + "type": "item_group", + "id": "cig_box_cigarette_20", + "subtype": "collection", + "//": "This group was created automatically and may contain errors.", + "container-item": "box_cigarette", + "entries": [ { "item": "cig", "container-item": "null", "count": 20 } ] } ] diff --git a/data/json/itemgroups/Food/food.json b/data/json/itemgroups/Food/food.json index d661eb8bf89eb..ecb965f996a1d 100644 --- a/data/json/itemgroups/Food/food.json +++ b/data/json/itemgroups/Food/food.json @@ -1484,5 +1484,13 @@ "//": "This group was created automatically and may contain errors.", "container-item": "bag_paper_powder", "entries": [ { "item": "soup_instant_vegetable_powder", "container-item": "null", "count": [ 1, 1 ] } ] + }, + { + "type": "item_group", + "id": "flour_bag_paper_powder_10", + "subtype": "collection", + "//": "This group was created automatically and may contain errors.", + "container-item": "bag_paper_powder", + "entries": [ { "item": "flour", "container-item": "null", "count": 10 } ] } ] diff --git a/data/json/itemgroups/Locations_MapExtras/locations_commercial.json b/data/json/itemgroups/Locations_MapExtras/locations_commercial.json index 033a09b0458f2..879aa5ed845df 100644 --- a/data/json/itemgroups/Locations_MapExtras/locations_commercial.json +++ b/data/json/itemgroups/Locations_MapExtras/locations_commercial.json @@ -1979,19 +1979,6 @@ { "item": "anesthetic_kit", "prob": 10, "charges": [ 0, -1 ] } ] }, - { - "id": "daycare_misc", - "type": "item_group", - "items": [ - [ "magnifying_glass", 2 ], - { "item": "sewing_kit", "prob": 1, "charges": [ 0, -1 ] }, - [ "scissors", 1 ], - [ "phonebook", 2 ], - { "item": "flashlight", "prob": 2, "charges": [ 0, 300 ] }, - [ "petpack", 1 ], - [ "mag_comic", 5 ] - ] - }, { "id": "daycare_kitchen", "type": "item_group", diff --git a/data/json/itemgroups/Monsters_Animals_Lairs/monster_drops_lairs.json b/data/json/itemgroups/Monsters_Animals_Lairs/monster_drops_lairs.json index 6a1b1cc5a7857..5017c071a3364 100644 --- a/data/json/itemgroups/Monsters_Animals_Lairs/monster_drops_lairs.json +++ b/data/json/itemgroups/Monsters_Animals_Lairs/monster_drops_lairs.json @@ -1,10 +1,4 @@ [ - { - "type": "item_group", - "id": "shia_stuff", - "subtype": "distribution", - "entries": [ { "item": "knife_small", "variant": "knife_steak", "prob": 3 }, { "item": "ax", "prob": 1 } ] - }, { "type": "item_group", "id": "monparts", @@ -120,44 +114,6 @@ "subtype": "distribution", "entries": [ { "item": "fighter_sting", "prob": 5 } ] }, - { - "type": "item_group", - "id": "vault_wanderer", - "magazine": 100, - "ammo": 20, - "subtype": "distribution", - "entries": [ - { "item": "jumpsuit", "prob": 90 }, - { "item": "mask_filter", "prob": 10, "charges": [ 0, 100 ] }, - { "group": "ammo_pocket_batteries_full", "prob": 10 }, - { "item": "radio", "prob": 10, "charges": [ 10, 95 ] }, - { "item": "boots_combat", "prob": 20 }, - { "item": "bandages", "prob": 10, "count": [ 1, 3 ] }, - { "prob": 30, "group": "cig_box_cigarette_1_20" }, - { "item": "knife_combat_army", "variant": "m9bayonet", "prob": 10 }, - { "item": "vest", "prob": 15 }, - { "item": "glasses_safety", "prob": 15 }, - { "item": "9mm", "prob": 15, "charges": [ 1, 50 ] }, - { "item": "m9", "prob": 10, "charges": [ 0, 15 ] }, - { "item": "water_clean", "prob": 10 }, - { "item": "eyedrops", "prob": 10, "count": [ 1, 10 ] }, - { "item": "steroid_eyedrops", "prob": 10, "count": [ 1, 10 ] }, - { "item": "screwdriver", "prob": 10 }, - { "group": "wallets_science", "prob": 5 }, - { "item": "cleansuit", "prob": 10 }, - { "item": "coat_lab", "prob": 20 }, - { "item": "glasses_eye", "prob": 30 }, - { "item": "rad_monitor", "prob": 10, "charges": [ 2, 20 ] }, - { "item": "geiger_off", "prob": 10, "charges": [ 10, 95 ] }, - { "item": "tool_belt", "prob": 15 }, - { "item": "panties", "prob": 20 }, - { "item": "boy_shorts", "prob": 20 }, - { "item": "bra", "prob": 20 }, - { "item": "undershirt", "prob": 40 }, - { "item": "boxer_shorts", "prob": 30 }, - { "item": "briefs", "prob": 30 } - ] - }, { "type": "item_group", "id": "cow", diff --git a/data/json/monsterdrops/feral_humans.json b/data/json/monsterdrops/feral_humans.json index f5c56c700efa1..87de96f173465 100644 --- a/data/json/monsterdrops/feral_humans.json +++ b/data/json/monsterdrops/feral_humans.json @@ -705,30 +705,6 @@ "id": "feral_swimmer_death_drops_kickboard", "entries": [ { "item": "stick", "prob": 100, "damage": [ 2, 4 ] }, { "group": "mon_zombie_swimmer_death_drops", "prob": 100 } ] }, - { - "type": "item_group", - "subtype": "collection", - "id": "default_diver_clothing_drops", - "entries": [ - { - "distribution": [ - { "item": "shark_suit", "damage": [ 1, 4 ], "prob": 5 }, - { - "collection": [ - { "group": "diving_suits", "damage": [ 1, 4 ], "prob": 95 }, - { "group": "diving_head", "damage": [ 1, 4 ], "prob": 40 }, - { "group": "diving_gloves", "damage": [ 1, 4 ], "prob": 50 }, - { "group": "diving_shoes", "damage": [ 1, 4 ], "prob": 50 } - ], - "prob": 95 - } - ] - }, - { "group": "diving_masks", "damage": [ 1, 4 ], "prob": 100 }, - { "group": "diving_glasses", "damage": [ 0, 4 ], "prob": 65 }, - { "group": "diving_accessories", "damage": [ 1, 4 ], "prob": 40 } - ] - }, { "id": "mon_feral_jackboot_death_drops", "type": "item_group", diff --git a/data/json/monsterdrops/misc.json b/data/json/monsterdrops/misc.json index d1d9ef9a41bf5..7989bafd7c4ec 100644 --- a/data/json/monsterdrops/misc.json +++ b/data/json/monsterdrops/misc.json @@ -1,16 +1,4 @@ [ - { - "type": "item_group", - "subtype": "collection", - "id": "jackson_drops", - "entries": [ - { "item": "jacket_leather_red", "prob": 100 }, - { "item": "jeans_red", "prob": 100 }, - { "item": "socks", "prob": 100 }, - { "item": "dance_shoes", "prob": 100 }, - { "item": "glove_jackson", "prob": 100 } - ] - }, { "type": "item_group", "subtype": "collection", diff --git a/data/mods/CrazyCataclysm/crazy_item_groups.json b/data/mods/CrazyCataclysm/crazy_item_groups.json index cb993a9a76c76..a0256a3256915 100644 --- a/data/mods/CrazyCataclysm/crazy_item_groups.json +++ b/data/mods/CrazyCataclysm/crazy_item_groups.json @@ -139,5 +139,23 @@ }, { "group": "party_rocker_death_drop", "prob": 100, "damage": [ 1, 3 ] } ] + }, + { + "type": "item_group", + "subtype": "collection", + "id": "jackson_drops", + "entries": [ + { "item": "jacket_leather_red", "prob": 100 }, + { "item": "jeans_red", "prob": 100 }, + { "item": "socks", "prob": 100 }, + { "item": "dance_shoes", "prob": 100 }, + { "item": "glove_jackson", "prob": 100 } + ] + }, + { + "type": "item_group", + "id": "shia_stuff", + "subtype": "distribution", + "entries": [ { "item": "knife_small", "variant": "knife_steak", "prob": 3 }, { "item": "ax", "prob": 1 } ] } ] diff --git a/data/json/itemgroups/defense_mode.json b/data/mods/Defense_Mode/itemgroups.json similarity index 70% rename from data/json/itemgroups/defense_mode.json rename to data/mods/Defense_Mode/itemgroups.json index dbc27d06e2531..250ebe3dbdfda 100644 --- a/data/json/itemgroups/defense_mode.json +++ b/data/mods/Defense_Mode/itemgroups.json @@ -139,45 +139,5 @@ { "item": "UPS_OFF" }, { "item": "mininuke" } ] - }, - { - "type": "item_group", - "id": "flour_bag_paper_powder_10", - "subtype": "collection", - "//": "This group was created automatically and may contain errors.", - "container-item": "bag_paper_powder", - "entries": [ { "item": "flour", "container-item": "null", "count": 10 } ] - }, - { - "type": "item_group", - "id": "codeine_bottle_plastic_pill_painkiller_10", - "subtype": "collection", - "//": "This group was created automatically and may contain errors.", - "container-item": "bottle_plastic_pill_painkiller", - "entries": [ { "item": "codeine", "container-item": "null", "count": 10 } ] - }, - { - "type": "item_group", - "id": "oxycodone_bottle_plastic_pill_prescription_10", - "subtype": "collection", - "//": "This group was created automatically and may contain errors.", - "container-item": "bottle_plastic_pill_prescription", - "entries": [ { "item": "oxycodone", "container-item": "null", "count": 10 } ] - }, - { - "type": "item_group", - "id": "cig_box_cigarette_20", - "subtype": "collection", - "//": "This group was created automatically and may contain errors.", - "container-item": "box_cigarette", - "entries": [ { "item": "cig", "container-item": "null", "count": 20 } ] - }, - { - "type": "item_group", - "id": "meth_bag_zipper_6", - "subtype": "collection", - "//": "This group was created automatically and may contain errors.", - "container-item": "bag_zipper", - "entries": [ { "item": "meth", "container-item": "null", "count": 6 } ] } ] diff --git a/data/mods/No_Hope/item_groups.json b/data/mods/No_Hope/item_groups.json index 87a2e1ae97912..c0378770347f4 100644 --- a/data/mods/No_Hope/item_groups.json +++ b/data/mods/No_Hope/item_groups.json @@ -367,5 +367,43 @@ { "item": "geiger_off", "prob": 10 }, { "item": "tool_belt", "prob": 15 } ] + }, + { + "type": "item_group", + "id": "vault_wanderer", + "magazine": 100, + "ammo": 20, + "subtype": "distribution", + "entries": [ + { "item": "jumpsuit", "prob": 90 }, + { "item": "mask_filter", "prob": 10, "charges": [ 0, 100 ] }, + { "group": "ammo_pocket_batteries_full", "prob": 10 }, + { "item": "radio", "prob": 10, "charges": [ 10, 95 ] }, + { "item": "boots_combat", "prob": 20 }, + { "item": "bandages", "prob": 10, "count": [ 1, 3 ] }, + { "prob": 30, "group": "cig_box_cigarette_1_20" }, + { "item": "knife_combat_army", "variant": "m9bayonet", "prob": 10 }, + { "item": "vest", "prob": 15 }, + { "item": "glasses_safety", "prob": 15 }, + { "item": "9mm", "prob": 15, "charges": [ 1, 50 ] }, + { "item": "m9", "prob": 10, "charges": [ 0, 15 ] }, + { "item": "water_clean", "prob": 10 }, + { "item": "eyedrops", "prob": 10, "count": [ 1, 10 ] }, + { "item": "steroid_eyedrops", "prob": 10, "count": [ 1, 10 ] }, + { "item": "screwdriver", "prob": 10 }, + { "group": "wallets_science", "prob": 5 }, + { "item": "cleansuit", "prob": 10 }, + { "item": "coat_lab", "prob": 20 }, + { "item": "glasses_eye", "prob": 30 }, + { "item": "rad_monitor", "prob": 10, "charges": [ 2, 20 ] }, + { "item": "geiger_off", "prob": 10, "charges": [ 10, 95 ] }, + { "item": "tool_belt", "prob": 15 }, + { "item": "panties", "prob": 20 }, + { "item": "boy_shorts", "prob": 20 }, + { "item": "bra", "prob": 20 }, + { "item": "undershirt", "prob": 40 }, + { "item": "boxer_shorts", "prob": 30 }, + { "item": "briefs", "prob": 30 } + ] } ] From d77e36da763826e4bf0493037b1d3d25b38884e5 Mon Sep 17 00:00:00 2001 From: Karol1223 <68503002+Karol1223@users.noreply.github.com> Date: Fri, 6 Sep 2024 22:03:16 +0200 Subject: [PATCH 11/12] Decentralize ``small_animal`` and ``fish`` factions (#75993) * mammals without bat, I wanna give that nerd a bird faction * fix dinomod * birds + bat * reptile + amphibian * Update monfactions_test.cpp * some test fixing * fish + molerat faction cleanup * predatory waterfowl + dachshunds * Update monster_factions.json * Update monster_factions.json * Update monster_factions.json * Update monster_factions.json * Update monster_factions.json --- data/json/monster_factions.json | 250 ++++++++++++++++++---- data/json/monsters/bird.json | 19 +- data/json/monsters/fish.json | 18 +- data/json/monsters/mammal.json | 33 +-- data/json/monsters/mollusk.json | 2 +- data/json/monsters/mutant_mammal.json | 2 +- data/json/monsters/reptile_amphibian.json | 24 ++- data/mods/DinoMod/monster_factions.json | 12 +- tests/monfactions_test.cpp | 8 +- 9 files changed, 276 insertions(+), 92 deletions(-) diff --git a/data/json/monster_factions.json b/data/json/monster_factions.json index 9a48b8fee6841..674f14007a4f4 100644 --- a/data/json/monster_factions.json +++ b/data/json/monster_factions.json @@ -54,14 +54,13 @@ "type": "MONSTER_FACTION", "name": "zombie_aquatic", "base_faction": "zombie", - "hate": [ "aquatic_predator", "kraken" ], - "by_mood": [ "fish" ] + "hate": [ "aquatic_predator", "kraken", "fish_large", "fish_mutant_passive" ] }, { "type": "MONSTER_FACTION", "name": "kraken", "hate": [ "aquatic_predator", "zombie_aquatic" ], - "by_mood": [ "fish" ] + "by_mood": [ "fish_medium", "fish_large", "fish_mutant_passive" ] }, { "type": "MONSTER_FACTION", @@ -93,9 +92,175 @@ "type": "MONSTER_FACTION", "name": "small_animal", "base_faction": "animal", - "friendly": [ "attack_player_only" ], - "neutral": [ "zombie", "fish", "exodii", "isolated_artisans", "nether", "animal", "yrax", "passive_machine" ], - "by_mood": [ "cat", "bear", "fox", "big_cat", "dog", "coyote", "wolf", "dog_small" ] + "//": "Base faction for animals roughly the size of a rabbit. Avoid giving this specific faction to monsters, instead check if there's a baby faction from this one that suits the monster better.", + "neutral": [ "zombie", "exodii", "isolated_artisans", "nether", "animal", "yrax" ], + "by_mood": [ "bear", "fox", "big_cat", "dog", "coyote", "wolf" ] + }, + { + "type": "MONSTER_FACTION", + "name": "mammal_small", + "base_faction": "small_animal", + "by_mood": "snake_small" + }, + { + "type": "MONSTER_FACTION", + "name": "mammal_small_predator", + "base_faction": "mammal_small", + "hate": [ "tiny_animal" ] + }, + { + "type": "MONSTER_FACTION", + "name": "opossum", + "base_faction": "mammal_small_predator" + }, + { + "type": "MONSTER_FACTION", + "name": "skunk", + "base_faction": "mammal_small_predator" + }, + { + "type": "MONSTER_FACTION", + "name": "raccoon", + "base_faction": "mammal_small_predator" + }, + { + "type": "MONSTER_FACTION", + "name": "ferret", + "base_faction": "mammal_small_predator" + }, + { + "type": "MONSTER_FACTION", + "name": "dog_small", + "base_faction": "mammal_small_predator", + "friendly": [ "dog" ] + }, + { + "type": "MONSTER_FACTION", + "name": "cat", + "base_faction": "mammal_small_predator" + }, + { + "type": "MONSTER_FACTION", + "name": "otter", + "base_faction": "mammal_small", + "neutral": "snake_small", + "hate": [ "fish_tiny", "fish_small", "fish_medium", "amphibian_tiny", "reptile_tiny_aquatic" ] + }, + { + "type": "MONSTER_FACTION", + "name": "bird_small_flying", + "base_faction": "small_animal" + }, + { + "type": "MONSTER_FACTION", + "name": "bird_small_flightless", + "base_faction": "small_animal" + }, + { + "type": "MONSTER_FACTION", + "name": "bird_small_waterfowl", + "base_faction": "small_animal" + }, + { + "type": "MONSTER_FACTION", + "name": "bird_small_waterfowl_predator", + "base_faction": "bird_small_waterfowl", + "hate": [ "amphibian_tiny", "fish_tiny", "fish_small", "snake_tiny_aquatic" ] + }, + { + "type": "MONSTER_FACTION", + "name": "reptile_small", + "base_faction": "small_animal" + }, + { + "type": "MONSTER_FACTION", + "name": "snake_small", + "base_faction": "reptile_small", + "neutral": [ "small_animal", "bird_tiny_flying", "otter" ], + "hate": [ "tiny_animal", "mammal_small" ] + }, + { + "type": "MONSTER_FACTION", + "name": "reptile_small_aquatic", + "base_faction": "small_animal" + }, + { + "type": "MONSTER_FACTION", + "name": "turtle_small", + "base_faction": "reptile_small_aquatic" + }, + { + "type": "MONSTER_FACTION", + "name": "turtle_small_predator", + "base_faction": "turtle_small", + "neutral": [ "bird_tiny_flying" ], + "hate": [ "tiny_animal", "fish_tiny", "fish_small" ] + }, + { + "type": "MONSTER_FACTION", + "name": "tiny_animal", + "base_faction": "small_animal", + "//": "Base faction for animals roughly the size of a rat or a squirrel. Avoid giving this specific faction to monsters, instead check if there's a baby faction from this one that suits the monster better.", + "neutral": [ "small_animal", "bear", "big_cat", "razorclaw", "mantis", "frog" ], + "by_mood": [ "mammal_small_predator", "weasel", "snake_tiny_aquatic", "snake_small", "turtle_small_predator" ] + }, + { + "type": "MONSTER_FACTION", + "name": "mammal_tiny", + "base_faction": "tiny_animal" + }, + { + "type": "MONSTER_FACTION", + "name": "weasel", + "base_faction": "mammal_tiny", + "hate": [ "tiny_animal", "mammal_tiny" ] + }, + { + "type": "MONSTER_FACTION", + "name": "bird_tiny_flying", + "base_faction": "tiny_animal", + "neutral": [ "snake_tiny_aquatic", "snake_small", "turtle_small_predator" ] + }, + { + "type": "MONSTER_FACTION", + "name": "bird_tiny_flightless", + "base_faction": "tiny_animal" + }, + { + "type": "MONSTER_FACTION", + "name": "bird_tiny_waterfowl", + "base_faction": "tiny_animal" + }, + { + "type": "MONSTER_FACTION", + "name": "amphibian_tiny", + "base_faction": "tiny_animal", + "by_mood": [ "otter", "bird_small_waterfowl_predator" ] + }, + { + "type": "MONSTER_FACTION", + "name": "reptile_tiny", + "base_faction": "tiny_animal" + }, + { + "type": "MONSTER_FACTION", + "name": "lizard_tiny", + "base_faction": "reptile_tiny" + }, + { + "type": "MONSTER_FACTION", + "name": "reptile_tiny_aquatic", + "base_faction": "tiny_animal", + "neutral": [ "snake_tiny_aquatic" ], + "by_mood": [ "otter" ] + }, + { + "type": "MONSTER_FACTION", + "name": "snake_tiny_aquatic", + "base_faction": "reptile_tiny_aquatic", + "neutral": [ "bird_tiny_flying", "reptile_tiny_aquatic" ], + "by_mood": [ "bird_small_waterfowl_predator" ], + "hate": [ "tiny_animal", "fish_tiny" ] }, { "type": "MONSTER_FACTION", @@ -110,16 +275,12 @@ "base_faction": "herbivore", "by_mood": [ "herbivore" ] }, - { - "type": "MONSTER_FACTION", - "name": "vermin", - "base_faction": "small_animal" - }, { "type": "MONSTER_FACTION", "name": "bear", "base_faction": "animal", "//": "Hunts small things, can't resist honey", + "neutral": [ "tiny_animal" ], "hate": [ "small_animal", "bee" ], "by_mood": [ "fish" ] }, @@ -133,27 +294,15 @@ "type": "MONSTER_FACTION", "name": "big_cat", "base_faction": "animal", + "neutral": [ "tiny_animal" ], "hate": [ "small_animal", "herbivore" ], "by_mood": [ "fish" ] }, - { - "type": "MONSTER_FACTION", - "name": "cat", - "base_faction": "small_animal", - "neutral": [ "dog_small" ], - "hate": [ "small_animal" ] - }, { "type": "MONSTER_FACTION", "name": "dog", "base_faction": "animal", - "hate": [ "small_animal" ] - }, - { - "type": "MONSTER_FACTION", - "name": "dog_small", - "base_faction": "small_animal", - "neutral": [ "cat" ], + "friendly": [ "dog_small" ], "hate": [ "small_animal" ] }, { @@ -176,15 +325,14 @@ { "type": "MONSTER_FACTION", "name": "rat", - "base_faction": "vermin", + "base_faction": "mammal_tiny", "neutral": [ "ratkin" ] }, { "type": "MONSTER_FACTION", "name": "fish", "base_faction": "animal", - "hate": [ "aquatic_predator", "zombie_aquatic", "mutant_piscivores", "crayfish", "strider", "beetle_diving", "water_scorpion" ], - "by_mood": [ "bear", "big_cat", "kraken", "fish_mutant_passive" ], + "by_mood": [ "bear", "big_cat", "aquatic_predator", "mutant_piscivores", "crayfish", "strider", "beetle_diving", "water_scorpion" ], "neutral": [ "zombie", "bot", @@ -202,21 +350,36 @@ "passive_machine" ] }, + { + "type": "MONSTER_FACTION", + "name": "fish_tiny", + "base_faction": "fish", + "by_mood": [ "otter", "turtle_small_predator", "snake_tiny_aquatic", "bird_small_waterfowl_predator" ] + }, + { + "type": "MONSTER_FACTION", + "name": "fish_small", + "base_faction": "fish", + "by_mood": [ "otter", "turtle_small_predator", "bird_small_waterfowl_predator" ] + }, + { + "type": "MONSTER_FACTION", + "name": "fish_medium", + "base_faction": "fish", + "by_mood": [ "otter", "kraken" ] + }, + { + "type": "MONSTER_FACTION", + "name": "fish_large", + "base_faction": "fish", + "by_mood": [ "kraken", "zombie_aquatic" ] + }, { "type": "MONSTER_FACTION", "name": "fish_mutant_passive", - "//": "This is for fish mutants that are either herbivores or carnivores but not aggressive enough to where they'd attack fish of similar size as them. They don't hate anyone because I don't want them all to blindly flail around the rivers murdering things if they're not predators.", + "//": "This is for fish mutants that are either herbivores or carnivores not aggressive enough to attack fish of similar size as them.", "base_faction": "fish", - "by_mood": [ - "fish", - "strider", - "aquatic_predator", - "zombie_aquatic", - "mutant_piscivores", - "crayfish", - "beetle_diving", - "water_scorpion" - ] + "by_mood": [ "kraken", "zombie_aquatic" ] }, { "type": "MONSTER_FACTION", @@ -288,12 +451,14 @@ "name": "razorclaw", "base_faction": "mutant", "//": "Protect their nest, grumpy", + "neutral": [ "tiny_animal" ], "by_mood": [ "small_animal" ] }, { "type": "MONSTER_FACTION", "name": "frog", "base_faction": "mutant", + "neutral": [ "tiny_animal" ], "by_mood": [ "animal" ], "hate": [ "small_animal", "insect" ] }, @@ -311,11 +476,6 @@ "by_mood": [ "mutant", "mutant_piscivores" ], "hate": [ "fish" ] }, - { - "type": "MONSTER_FACTION", - "name": "molerat", - "base_faction": "mutant" - }, { "type": "MONSTER_FACTION", "name": "amigara", @@ -403,7 +563,6 @@ "frog", "slug", "mutant_piscivores", - "molerat", "amigara", "mutant_with_vortex", "corvid", @@ -595,6 +754,7 @@ "type": "MONSTER_FACTION", "name": "mantis", "base_faction": "insect", + "neutral": [ "tiny_animal" ], "by_mood": [ "centipede", "spider", "ant", "acid_ant" ], "hate": [ "insect", "small_animal" ] }, diff --git a/data/json/monsters/bird.json b/data/json/monsters/bird.json index 122345bc3d57c..bab0f4800da7f 100644 --- a/data/json/monsters/bird.json +++ b/data/json/monsters/bird.json @@ -5,7 +5,7 @@ "name": { "str": "flying bird abstract" }, "description": "This is an abstract monster for other flying birds to copy from, so that we have some common foundation to work with. If it appears in the game that's a bug. Use this when your bird can fly, but cannot swim.", "bodytype": "bird", - "default_faction": "small_animal", + "default_faction": "bird_small_flying", "categories": [ "WILDLIFE" ], "species": [ "BIRD" ], "volume": "467 ml", @@ -50,6 +50,7 @@ "name": { "str": "flightless bird abstract" }, "description": "This is an abstract monster for other flightless birds to copy from, so that we have some common foundation to work with. If it appears in the game that's a bug. Use this when your bird can neither fly nor swim.", "copy-from": "mon_bird_flying_base", + "default_faction": "bird_small_flightless", "speed": 105, "delete": { "flags": [ "FLIES" ] } }, @@ -59,6 +60,7 @@ "name": { "str": "water bird abstract" }, "description": "This is an abstract monster for other water birds to copy from, so that we have some common foundation to work with. If it appears in the game that's a bug. Use this when your bird can both fly and swim.", "copy-from": "mon_bird_flying_base", + "default_faction": "bird_small_waterfowl", "speed": 85, "extend": { "flags": [ "SWIMS" ] } }, @@ -67,7 +69,7 @@ "type": "MONSTER", "name": { "str": "brown chick" }, "description": "A tiny darkly-colored chick, it could be from a number of different species.", - "default_faction": "small_animal", + "default_faction": "bird_tiny_flightless", "bodytype": "bird", "categories": [ "WILDLIFE" ], "species": [ "BIRD" ], @@ -121,6 +123,7 @@ "name": { "str": "waterfowl chick" }, "description": "A tiny yellow and brown waterfowl chick, it could be from a number of different species.", "copy-from": "mon_generic_chick", + "default_faction": "bird_tiny_waterfowl", "upgrades": { "age_grow": 14, "into": "mon_duck" }, "//": "Grows up into a duck as a fallback", "extend": { "flags": [ "SWIMS" ] } @@ -191,6 +194,7 @@ "name": { "str": "blue jay" }, "description": "A small, noisy bird with distinctive blue feathers.", "copy-from": "mon_bird_flying_base", + "default_faction": "bird_tiny_flying", "volume": "120 ml", "weight": "90 g", "color": "light_blue", @@ -202,6 +206,7 @@ "name": { "str": "cardinal" }, "description": "A small songbird, famous for its distinctive crest and facial markings. A well-known example of sexual dimorphism, the males are colored much more vibrantly than the females.", "copy-from": "mon_bird_flying_base", + "default_faction": "bird_tiny_flying", "volume": "60 ml", "weight": "45 g", "color": "red", @@ -213,6 +218,7 @@ "name": { "str": "American robin" }, "description": "A brown songbird with a reddish-orange breast. Their eggs are a distinctive shade of blue.", "copy-from": "mon_bird_flying_base", + "default_faction": "bird_tiny_flying", "volume": "103 ml", "weight": "77 g", "color": "brown", @@ -224,6 +230,7 @@ "name": { "str": "house sparrow" }, "description": "A small bird with brown and gray feathers. Introduced to North America in the 1850s, it is now one of the most abundant birds in the continent.", "copy-from": "mon_bird_flying_base", + "default_faction": "bird_tiny_flying", "volume": "40 ml", "weight": "30 g", "reproduction": { "baby_egg": "egg_sparrow", "baby_count": 5, "baby_timer": 16 } @@ -234,6 +241,7 @@ "name": { "str": "black-capped chickadee" }, "description": "A tiny species of tit native to North America, with a distinctive black cap on its head.", "copy-from": "mon_bird_flying_base", + "default_faction": "bird_tiny_flying", "volume": "16 ml", "weight": "12 g", "reproduction": { "baby_egg": "egg_chickadee", "baby_count": 8, "baby_timer": 14 } @@ -250,6 +258,7 @@ "name": { "str": "cedar waxwing" }, "description": "A small species of waxwing with a distinctive feathered crest and a black mask pattern on its face.", "copy-from": "mon_bird_flying_base", + "default_faction": "bird_tiny_flying", "volume": "40 ml", "weight": "30 g", "reproduction": { "baby_egg": "egg_waxwing", "baby_count": 5, "baby_timer": 16 } @@ -617,6 +626,7 @@ "name": { "str": "ruby-throated hummingbird" }, "description": "A very small hummingbird of varied colorful feathers. It flies at incredible speeds while seeking nectar among flowers.", "copy-from": "mon_bird_flying_base", + "default_faction": "bird_tiny_flying", "volume": "5 ml", "weight": "3600 mg", "color": "light_green", @@ -629,6 +639,7 @@ "name": { "str": "downy woodpecker" }, "description": "A small bird with woody colors and a colored crest on its head. Well known for its ability to poke holes on trees while looking for grubs.", "copy-from": "mon_bird_flying_base", + "default_faction": "bird_tiny_flying", "volume": "35 ml", "weight": "26 g", "reproduction": { "baby_egg": "egg_woodpecker", "baby_count": 5, "baby_timer": 30 } @@ -658,9 +669,10 @@ { "id": "mon_cormorant", "type": "MONSTER", - "copy-from": "mon_coot", "name": { "str": "double-crested cormorant" }, "description": "An aquatic bird with a long snake-like neck. While often considered coastal birds, they feel just as at home in freshwater habitats.", + "copy-from": "mon_bird_water_base", + "default_faction": "bird_small_waterfowl_predator", "volume": "2467 ml", "weight": "1850 g", "hp": 5, @@ -684,6 +696,7 @@ "name": { "str": "horned grebe" }, "description": "A medium-sized aquatic bird with a long neck. They can be distinguished by their strange leg placement which makes them great at diving.", "copy-from": "mon_bird_water_base", + "default_faction": "bird_small_waterfowl_predator", "volume": "580 ml", "weight": "435 g", "color": "brown", diff --git a/data/json/monsters/fish.json b/data/json/monsters/fish.json index d0c89d8ed4e7c..7dc12a37bd640 100644 --- a/data/json/monsters/fish.json +++ b/data/json/monsters/fish.json @@ -46,7 +46,7 @@ "name": { "str_sp": "tiny fish" }, "//": "a default fish type - does not appear in-game", "description": "A tiny fish.", - "default_faction": "fish", + "default_faction": "fish_tiny", "bodytype": "fish", "categories": [ "WILDLIFE" ], "species": [ "FISH" ], @@ -77,7 +77,7 @@ "name": { "str_sp": "small fish" }, "//": "a default fish type - does not appear in-game", "description": "A small fish.", - "default_faction": "fish", + "default_faction": "fish_small", "bodytype": "fish", "categories": [ "WILDLIFE" ], "species": [ "FISH" ], @@ -107,7 +107,7 @@ "abstract": "mon_fish_medium", "type": "MONSTER", "description": "A medium fish.", - "default_faction": "fish", + "default_faction": "fish_medium", "name": { "str_sp": "medium fish" }, "//": "a default fish type - does not appear in-game", "bodytype": "fish", @@ -139,7 +139,7 @@ "abstract": "mon_fish_large", "type": "MONSTER", "description": "A large fish.", - "default_faction": "fish", + "default_faction": "fish_large", "bodytype": "fish", "categories": [ "WILDLIFE" ], "species": [ "FISH" ], @@ -171,7 +171,7 @@ "abstract": "mon_fish_huge", "type": "MONSTER", "description": "A huge fish.", - "default_faction": "fish", + "default_faction": "fish_large", "bodytype": "fish", "categories": [ "WILDLIFE" ], "species": [ "FISH" ], @@ -204,7 +204,7 @@ "name": { "str_sp": "fish fry" }, "//": "a default fish type - does not appear in-game", "description": "A minuscule half-translucent fish larva. Impossible to identify which species it belongs to.", - "default_faction": "fish", + "default_faction": "fish_tiny", "bodytype": "fish", "categories": [ "WILDLIFE" ], "species": [ "FISH" ], @@ -917,7 +917,7 @@ "type": "MONSTER", "name": { "str": "lobster" }, "description": "A dark greenish crustacean in its natural habitat. These were once considered pests barely worth eating, then some marketing genius started selling them to people as a delicacy and they took off in popularity… and price.", - "default_faction": "fish", + "default_faction": "fish_medium", "bodytype": "crab", "categories": [ "WILDLIFE" ], "species": [ "FISH" ], @@ -946,7 +946,7 @@ "type": "MONSTER", "name": { "str_sp": "crayfish" }, "description": "This crustacean looks like a tiny lobster, but is actually a completely different species. If you could get ahold of a bunch more of these, a hefty pot of boiling water, and some spicy seasonings…", - "default_faction": "fish", + "default_faction": "fish_tiny", "bodytype": "crab", "categories": [ "WILDLIFE" ], "species": [ "FISH" ], @@ -984,7 +984,7 @@ "type": "MONSTER", "name": { "str": "American eel" }, "description": "An American eel. They used to be quite common in these parts until the dams were built. They'll get a second chance now that those aren't running.", - "default_faction": "fish", + "default_faction": "fish_medium", "bodytype": "snake", "categories": [ "WILDLIFE" ], "species": [ "FISH" ], diff --git a/data/json/monsters/mammal.json b/data/json/monsters/mammal.json index 1d0c6691a27e0..3ab7ec699b9b6 100644 --- a/data/json/monsters/mammal.json +++ b/data/json/monsters/mammal.json @@ -47,7 +47,8 @@ "type": "MONSTER", "name": { "str": "bat" }, "description": "One of the vesper bats, a family of winged insect-eating mammals. It roosts in caves and other hollows, and uses a form of echolocation to aerially navigate through tricky terrain at rapid speeds.", - "default_faction": "small_animal", + "default_faction": "bird_small_flying", + "//": "I ain't about to make a unique bat faction when I don't know any predators specialized in hunting bats but not birds. Batman's gotta make do.", "bodytype": "bird", "categories": [ "WILDLIFE" ], "species": [ "MAMMAL" ], @@ -666,7 +667,7 @@ "type": "MONSTER", "name": { "str": "chipmunk" }, "description": "The eastern chipmunk, a tiny omnivorous rodent with a characteristic striped coat. It spends much of the day patrolling its elaborate burrow and the precious stores of foraged food within.", - "default_faction": "small_animal", + "default_faction": "mammal_tiny", "bodytype": "pig", "categories": [ "WILDLIFE" ], "species": [ "MAMMAL" ], @@ -1349,6 +1350,7 @@ "type": "MONSTER", "name": { "str": "dachshund" }, "description": "A wiener dog! This awkward looking dog can be a useful watchdog, plus it looks adorable as it bumbles around. Needless to say, it doesn't make a good attack dog.", + "default_faction": "dog_small", "hp": 10, "weight": "10 kg", "aggression": -4, @@ -1367,6 +1369,7 @@ "copy-from": "mon_dog_pup", "name": { "str": "dachshund puppy", "str_pl": "dachshund puppies" }, "description": "An adorable, defenseless dachshund puppy. Much safer to tame than an adult dog.", + "default_faction": "dog_small", "aggression": -12, "morale": 5, "melee_skill": 1, @@ -1607,7 +1610,7 @@ "type": "MONSTER", "name": { "str": "groundhog" }, "description": "Also known as the woodchuck, this ground squirrel has no actual talent for chucking wood.", - "default_faction": "small_animal", + "default_faction": "mammal_small", "bodytype": "pig", "categories": [ "WILDLIFE" ], "species": [ "MAMMAL" ], @@ -1770,7 +1773,7 @@ "type": "MONSTER", "name": { "str": "lemming" }, "description": "The Northern bog lemming, a small, predominantly vegetarian rodent that spends its life in the murk of swamps and other wetlands. Contrary to popular belief, these creatures are not particularly hapless or suicidal, but they can eat themselves into scarcity within a few generations.", - "default_faction": "small_animal", + "default_faction": "mammal_tiny", "bodytype": "pig", "categories": [ "WILDLIFE" ], "species": [ "MAMMAL" ], @@ -1798,7 +1801,7 @@ "type": "MONSTER", "name": { "str": "mink" }, "description": "The American mink, a partially aquatic weasel, once factory-farmed for its fur. It is a capable fisher, but the presence of otters in these parts makes it rely more on food from the land.", - "default_faction": "small_animal", + "default_faction": "mammal_small", "bodytype": "dog", "categories": [ "WILDLIFE" ], "species": [ "MAMMAL" ], @@ -1986,7 +1989,7 @@ "type": "MONSTER", "name": { "str": "muskrat" }, "description": "A large omnivorous rodent with a thick furry pelt, found in wetlands across the Northern Hemisphere. It marks its territory with a musky odor for which it is named.", - "default_faction": "small_animal", + "default_faction": "mammal_small", "bodytype": "pig", "categories": [ "WILDLIFE" ], "species": [ "MAMMAL" ], @@ -2015,7 +2018,7 @@ "type": "MONSTER", "name": { "str": "opossum" }, "description": "The Virginia opossum, a small omnivorous marsupial native to North America. About the size of a cat, it is hardy and adaptive, and a fairly common sight in urban areas.", - "default_faction": "small_animal", + "default_faction": "opossum", "bodytype": "pig", "categories": [ "WILDLIFE" ], "species": [ "MAMMAL" ], @@ -2046,7 +2049,7 @@ "type": "MONSTER", "name": { "str": "skunk" }, "description": "The common striped skunk, similar in size to opossum or domestic cats, these mammals can often be smelled before they are seen.", - "default_faction": "small_animal", + "default_faction": "skunk", "bodytype": "pig", "categories": [ "WILDLIFE" ], "species": [ "MAMMAL" ], @@ -2100,7 +2103,7 @@ "type": "MONSTER", "name": { "str": "otter" }, "description": "The North American river otter, a shy water-dwelling relative of the weasel that lives in large families along the banks of streams. It is an excellent fisher and a resourceful survivor, using the abandoned dens of beavers and other animals to raise its own young.", - "default_faction": "small_animal", + "default_faction": "otter", "bodytype": "pig", "categories": [ "WILDLIFE" ], "species": [ "MAMMAL" ], @@ -2226,7 +2229,7 @@ "type": "MONSTER", "name": { "str": "rabbit" }, "description": "Rabbit abstract", - "default_faction": "small_animal", + "default_faction": "mammal_small", "bodytype": "pig", "categories": [ "WILDLIFE" ], "species": [ "MAMMAL" ], @@ -2318,7 +2321,7 @@ "type": "MONSTER", "name": { "str": "raccoon" }, "description": "A small mammal native to North America, distinctive for its dexterous paws and facial markings. It is resourceful and agile enough to open sealed containers in search of food.", - "default_faction": "small_animal", + "default_faction": "raccoon", "bodytype": "pig", "categories": [ "WILDLIFE" ], "species": [ "MAMMAL" ], @@ -2519,7 +2522,7 @@ "type": "MONSTER", "name": { "str": "squirrel" }, "description": "A small granivorous rodent with a long bushy tail, often seen darting amid the branches of trees. A skittish varmint with an expression of unwavering austerity, it is the mortal enemy of cat and dog alike.", - "default_faction": "small_animal", + "default_faction": "mammal_tiny", "bodytype": "pig", "categories": [ "WILDLIFE" ], "species": [ "MAMMAL" ], @@ -2549,7 +2552,7 @@ "type": "MONSTER", "name": { "str": "squirrel" }, "description": "A tiny opportunistic rodent with a long bushy tail. The pine squirrel is clever and cute, and hunted by nearly everything in the woods with a taste for meat.", - "default_faction": "small_animal", + "default_faction": "mammal_tiny", "bodytype": "pig", "categories": [ "WILDLIFE" ], "species": [ "MAMMAL" ], @@ -2581,7 +2584,7 @@ "name": { "str": "weasel" }, "description": "The long-tailed weasel, a small but ubiquitous predator whose range extends across the continent. It forms its den in small burrows, preferring to occupy the nesting holes of its prey.", "bodytype": "pig", - "default_faction": "small_animal", + "default_faction": "weasel", "categories": [ "WILDLIFE" ], "species": [ "MAMMAL" ], "volume": "150 ml", @@ -2822,7 +2825,7 @@ "name": { "str": "ferret" }, "description": "Domesticated from the European polecat, this sleek and energetic mammal was commonly kept as a pet before the Cataclysm.", "bodytype": "pig", - "default_faction": "small_animal", + "default_faction": "ferret", "categories": [ "WILDLIFE" ], "species": [ "MAMMAL" ], "volume": "120 ml", diff --git a/data/json/monsters/mollusk.json b/data/json/monsters/mollusk.json index 009188ee7ddfb..086f62c05e370 100644 --- a/data/json/monsters/mollusk.json +++ b/data/json/monsters/mollusk.json @@ -5,7 +5,7 @@ "name": { "str": "freshwater snail" }, "description": "A tiny and shelled aquatic gastropod of either native or introduced stock. Dangerous to eat raw but properly cooked and cleaned it may serve as a fine dish.", "//": "this creature should be harvestable using crap pots or fish traps but requires extra work to convert from monster to item", - "default_faction": "fish", + "default_faction": "fish_tiny", "categories": [ "WILDLIFE" ], "species": [ "MOLLUSK" ], "volume": "300 ml", diff --git a/data/json/monsters/mutant_mammal.json b/data/json/monsters/mutant_mammal.json index 2af009b1f480a..1760334c9209b 100644 --- a/data/json/monsters/mutant_mammal.json +++ b/data/json/monsters/mutant_mammal.json @@ -96,7 +96,7 @@ "type": "MONSTER", "name": { "str": "feaver" }, "description": "This mutant beaver's body is covered with brightly-colored feathers in a particularly eyecatching pattern. It must have been very lucky not to have been caught by a predator before now.", - "default_faction": "small_animal", + "default_faction": "herbivore", "bodytype": "bear", "categories": [ "WILDLIFE" ], "species": [ "MAMMAL" ], diff --git a/data/json/monsters/reptile_amphibian.json b/data/json/monsters/reptile_amphibian.json index 8ec941a5786c6..0d2f6e3dce31b 100644 --- a/data/json/monsters/reptile_amphibian.json +++ b/data/json/monsters/reptile_amphibian.json @@ -4,7 +4,7 @@ "type": "MONSTER", "name": { "str": "abstract snake" }, "description": "This is an abstract monster for other snakes to copy from, so that we have some common foundation to work with. If it appears in the game that's a bug.", - "default_faction": "small_animal", + "default_faction": "snake_small", "bodytype": "snake", "categories": [ "WILDLIFE" ], "species": [ "REPTILE" ], @@ -15,7 +15,7 @@ "material": [ "flesh" ], "symbol": "s", "color": "brown", - "aggression": 15, + "aggression": 8, "morale": 60, "aggro_character": false, "melee_skill": 2, @@ -66,7 +66,7 @@ "type": "MONSTER", "name": { "str": "abstract turtle" }, "description": "This is an abstract monster for other turtles to copy from, so that we have some common foundation to work with. If it appears in the game that's a bug.", - "default_faction": "small_animal", + "default_faction": "turtle_small", "bodytype": "turtle", "categories": [ "WILDLIFE" ], "species": [ "REPTILE" ], @@ -78,6 +78,7 @@ "symbol": "o", "color": "brown", "aggression": 5, + "aggro_character": false, "morale": 60, "melee_skill": 2, "melee_dice": 1, @@ -141,6 +142,7 @@ "name": { "str": "common garter snake" }, "description": "A common species of snake found all across North America.", "copy-from": "mon_snake_abstract", + "default_faction": "snake_tiny_aquatic", "reproduction": { "baby_monster": "mon_gartersnake_baby", "baby_count": 10, "baby_timer": 90 }, "//": "The numbers here can technically go up to 80 snakelets, with averages reaching 40, but lets be honest the game couldn't handle that.", "baby_flags": [ "SUMMER" ] @@ -151,6 +153,7 @@ "name": { "str": "common garter snake snakelet" }, "description": "A garter snake in its juvenile stage.", "copy-from": "mon_snakelet_abstract", + "default_faction": "snake_tiny_aquatic", "upgrades": { "age_grow": 136, "into": "mon_gartersnake" } }, { @@ -159,9 +162,11 @@ "name": { "str": "worm snake" }, "description": "A small burrowing reptile that's just enjoying its time hunting earthworms.", "copy-from": "mon_snake_abstract", + "default_faction": "lizard_tiny", + "//1": "The reason its using the lizard faction is that it feeds on worms, so it can't use the snake factions that hunt other small animals.", "volume": "25 ml", "weight": "25 g", - "//": "Actually no info on weight, I just kinda assumed 1g per 1cm of length since they're tiny.", + "//2": "Actually no info on weight, I just kinda assumed 1g per 1cm of length since they're tiny.", "speed": 70, "vision_day": 6, "vision_night": 6, @@ -174,6 +179,7 @@ "type": "MONSTER", "name": { "str": "worm snake snakelet" }, "description": "A worm snake in its hatchling stage. Not that much smaller than an adult, actually.", + "default_faction": "lizard_tiny", "copy-from": "mon_snakelet_abstract", "upgrades": { "age_grow": 75, "into": "mon_wormsnake" }, "extend": { "fear_triggers": [ "BRIGHT_LIGHT" ] } @@ -205,6 +211,7 @@ "name": { "str": "common snapping turtle" }, "description": "A prehistoric-looking species of freshwater turtle with a nasty bite.", "copy-from": "mon_turtle_abstract", + "default_faction": "turtle_small_predator", "volume": "6 L", "weight": "6 kg", "hp": 16, @@ -223,6 +230,7 @@ "name": { "str": "common snapping turtle hatchling" }, "description": "A common snapping turtle in its hatchling stage.", "copy-from": "mon_turtle_baby_abstract", + "default_faction": "turtle_small_predator", "upgrades": { "age_grow": 1095, "into": "mon_turtle_snapping_common" }, "//": "12 years to reach maturity. It should probably be 15 years, because we're reaching the Northern range of the species in the setting, but odds are nobody is ever gonna see those grow to adulthood anyway." }, @@ -231,7 +239,7 @@ "type": "MONSTER", "name": { "str": "five-lined skink" }, "description": "A small species of skink. The only native lizard of New England.", - "default_faction": "small_animal", + "default_faction": "lizard_tiny", "bodytype": "lizard", "categories": [ "WILDLIFE" ], "species": [ "REPTILE" ], @@ -460,7 +468,7 @@ "type": "MONSTER", "description": "The larval form of some species of frog. This one is only hypothetical and you shouldn't be seeing it without debug.", "name": { "str": "tadpole" }, - "default_faction": "fish", + "default_faction": "fish_tiny", "bodytype": "fish", "categories": [ "WILDLIFE" ], "species": [ "AMPHIBIAN" ], @@ -667,7 +675,7 @@ "type": "MONSTER", "description": "A tadpole the size of a bass. It could win awards if it hadn't been debugged.", "name": { "str": "giant tadpole" }, - "default_faction": "fish", + "default_faction": "fish_small", "bodytype": "fish", "species": [ "AMPHIBIAN" ], "volume": "2 L", @@ -733,7 +741,7 @@ "type": "MONSTER", "description": "A hypothetical frog, if you're seeing this there's a problem.", "name": { "str": "proxy frog" }, - "default_faction": "small_animal", + "default_faction": "amphibian_tiny", "bodytype": "frog", "looks_like": "mon_frog", "categories": [ "WILDLIFE" ], diff --git a/data/mods/DinoMod/monster_factions.json b/data/mods/DinoMod/monster_factions.json index 942e4a1a41344..9f53fb244d0a3 100644 --- a/data/mods/DinoMod/monster_factions.json +++ b/data/mods/DinoMod/monster_factions.json @@ -3,8 +3,8 @@ "type": "MONSTER_FACTION", "name": "very_small_predator", "base_faction": "cat", - "by_mood": [ "small_animal", "cat", "very_small_predator" ], - "hate": [ "vermin" ] + "by_mood": [ "small_animal", "very_small_predator" ], + "hate": [ "tiny_animal" ] }, { "type": "MONSTER_FACTION", @@ -17,7 +17,7 @@ "type": "MONSTER_FACTION", "name": "medium_predator", "base_faction": "wolf", - "by_mood": [ "wolf", "medium_predator", "zombie_aquatic", "vermin" ] + "by_mood": [ "wolf", "medium_predator", "zombie_aquatic" ] }, { "type": "MONSTER_FACTION", @@ -70,7 +70,7 @@ "base_faction": "very_small_predator", "neutral": [ "fishing_dino", "zombie_aquatic", "mixed_dino" ], "by_mood": [ "very_small_mixed", "small_fisher" ], - "hate": [ "fish", "vermin" ] + "hate": [ "fish", "tiny_animal" ] }, { "type": "MONSTER_FACTION", @@ -86,13 +86,13 @@ "base_faction": "small_predator", "neutral": [ "fishing_dino", "zombie_aquatic", "mixed_dino" ], "by_mood": [ "small_mixed", "small_fisher" ], - "hate": [ "fish", "vermin" ] + "hate": [ "fish", "tiny_animal" ] }, { "type": "MONSTER_FACTION", "name": "medium_mixed", "base_faction": "big_cat", - "by_mood": [ "big_cat", "medium_mixed", "vermin", "aquatic_predator" ], + "by_mood": [ "big_cat", "medium_mixed", "tiny_animal", "aquatic_predator" ], "hate": [ "fish" ] }, { diff --git a/tests/monfactions_test.cpp b/tests/monfactions_test.cpp index 009cb4cee1e26..01c11075609fb 100644 --- a/tests/monfactions_test.cpp +++ b/tests/monfactions_test.cpp @@ -15,7 +15,7 @@ static const mfaction_str_id monfaction_test_monfaction3( "test_monfaction3" ); static const mfaction_str_id monfaction_test_monfaction5( "test_monfaction5" ); static const mfaction_str_id monfaction_test_monfaction7( "test_monfaction7" ); static const mfaction_str_id monfaction_test_monfaction_extend( "test_monfaction_extend" ); -static const mfaction_str_id monfaction_vermin( "vermin" ); +static const mfaction_str_id monfaction_tiny_animal( "tiny_animal" ); static std::string att_enum_to_string( mf_attitude att ) { @@ -106,7 +106,7 @@ TEST_CASE( "monfactions_attitude", "[monster][monfactions]" ) // based on the current state of json REQUIRE( attitude( "animal", "small_animal" ) == MFA_NEUTRAL ); REQUIRE( monfaction_small_animal->base_faction == monfaction_animal ); - REQUIRE( monfaction_vermin->base_faction == monfaction_small_animal ); + REQUIRE( monfaction_tiny_animal->base_faction == monfaction_small_animal ); REQUIRE( monfaction_fish->base_faction == monfaction_animal ); REQUIRE( monfaction_bear->base_faction == monfaction_animal ); @@ -120,8 +120,8 @@ TEST_CASE( "monfactions_attitude", "[monster][monfactions]" ) INFO( "fish is inherited from animal and should be neutral toward small_animal" ); CHECK( attitude( "fish", "small_animal" ) == MFA_NEUTRAL ); - INFO( "dog is inherited from animal, but hates small animals, of which vermin is a child" ); - CHECK( attitude( "dog", "vermin" ) == MFA_HATE ); + INFO( "dog is inherited from animal, but hates small animals, of which tiny_animal is a child" ); + CHECK( attitude( "dog", "tiny_animal" ) == MFA_HATE ); CHECK( attitude( "dog", "fish" ) == MFA_NEUTRAL ); } From e398be14514639f1e6aa512d8fd39c908b347eed Mon Sep 17 00:00:00 2001 From: Standing-Storm <120433252+Standing-Storm@users.noreply.github.com> Date: Fri, 6 Sep 2024 20:10:43 -0500 Subject: [PATCH 12/12] [MoM] Remove remaining Damage Balancing references (#76244) * Initial commit * Update recipe learning EoCs * Update data/mods/MindOverMatter/powers/vitakinesis_eoc.json Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../effectoncondition/eoc_learn_recipes.json | 14 +++++++------- data/mods/MindOverMatter/hobbies.json | 6 +++--- .../powers/learning_eocs/vitakinesis.json | 6 +++--- .../MindOverMatter/powers/vitakinesis_eoc.json | 1 - data/mods/MindOverMatter/recipes/research.json | 2 +- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/data/mods/MindOverMatter/effectoncondition/eoc_learn_recipes.json b/data/mods/MindOverMatter/effectoncondition/eoc_learn_recipes.json index 0b0234606031b..343b47dd73ffa 100644 --- a/data/mods/MindOverMatter/effectoncondition/eoc_learn_recipes.json +++ b/data/mods/MindOverMatter/effectoncondition/eoc_learn_recipes.json @@ -1025,12 +1025,12 @@ "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_SLOW_BLEEDING", "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_HEALTH_POWER", "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_STOP_BLEEDING", + "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_CONCENTRATED_HEALING", "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_HURT_TOUCH", "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_HEALING_TOUCH", "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_REMOVE_POISON", "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_CURE_DISEASE", "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_SLEEPING_TRANCE", - "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_PAIN_SPLIT", "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_STOP_INFECTION", "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_HEALING_TRANCE", "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_ATTACK_TOUCH", @@ -1061,6 +1061,12 @@ "condition": { "and": [ { "u_has_trait": "VITAKINETIC" }, { "math": [ "u_spell_level('vita_stop_bleeding')", ">=", "0" ] } ] }, "effect": [ { "u_learn_recipe": "practice_vita_stop_bleeding" } ] }, + { + "type": "effect_on_condition", + "id": "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_CONCENTRATED_HEALING", + "condition": { "and": [ { "u_has_trait": "VITAKINETIC" }, { "math": [ "u_spell_level('vita_concentrated_healing')", ">=", "0" ] } ] }, + "effect": [ { "u_learn_recipe": "practice_vita_concentrated_healing" } ] + }, { "type": "effect_on_condition", "id": "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_HURT_TOUCH", @@ -1091,12 +1097,6 @@ "condition": { "and": [ { "u_has_trait": "VITAKINETIC" }, { "math": [ "u_spell_level('vita_sleeping_trance')", ">=", "0" ] } ] }, "effect": [ { "u_learn_recipe": "practice_vita_sleeping_trance" } ] }, - { - "type": "effect_on_condition", - "id": "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_PAIN_SPLIT", - "condition": { "and": [ { "u_has_trait": "VITAKINETIC" }, { "math": [ "u_spell_level('vita_pain_split')", ">=", "0" ] } ] }, - "effect": [ { "u_learn_recipe": "practice_vita_pain_split" } ] - }, { "type": "effect_on_condition", "id": "EOC_CHECK_GAMEBEGIN_VITAKIN_RECIPE_STOP_INFECTION", diff --git a/data/mods/MindOverMatter/hobbies.json b/data/mods/MindOverMatter/hobbies.json index 8d3b1d8cb08e6..c511d19789d58 100644 --- a/data/mods/MindOverMatter/hobbies.json +++ b/data/mods/MindOverMatter/hobbies.json @@ -480,11 +480,11 @@ { "id": "vita_health_power", "level": 8 }, { "id": "vita_slow_bleeding", "level": 8 }, { "id": "vita_stop_bleeding", "level": 6 }, + { "id": "vita_concentrated_healing", "level": 6 }, { "id": "vita_health_power_ally", "level": 4 }, { "id": "vita_remove_poison", "level": 6 }, { "id": "vita_sleeping_trance", "level": 5 }, - { "id": "vita_cure_disease", "level": 5 }, - { "id": "vita_pain_split", "level": 6 } + { "id": "vita_cure_disease", "level": 5 } ] }, { @@ -500,11 +500,11 @@ { "id": "vita_health_power", "level": 10 }, { "id": "vita_slow_bleeding", "level": 9 }, { "id": "vita_stop_bleeding", "level": 8 }, + { "id": "vita_concentrated_healing", "level": 8 }, { "id": "vita_health_power_ally", "level": 8 }, { "id": "vita_remove_poison", "level": 6 }, { "id": "vita_sleeping_trance", "level": 7 }, { "id": "vita_cure_disease", "level": 7 }, - { "id": "vita_pain_split", "level": 8 }, { "id": "vita_stop_infection", "level": 12 }, { "id": "vita_healing_trance", "level": 6 }, { "id": "vita_blood_purge", "level": 6 }, diff --git a/data/mods/MindOverMatter/powers/learning_eocs/vitakinesis.json b/data/mods/MindOverMatter/powers/learning_eocs/vitakinesis.json index 08aa1347c8223..956931e44fa73 100644 --- a/data/mods/MindOverMatter/powers/learning_eocs/vitakinesis.json +++ b/data/mods/MindOverMatter/powers/learning_eocs/vitakinesis.json @@ -301,7 +301,7 @@ { "and": [ { "math": [ "u_spell_level('vita_stop_infection')", ">=", "5" ] }, - { "math": [ "u_spell_level('vita_pain_split')", ">=", "6" ] } + { "math": [ "u_spell_level('vita_concentrated_healing')", ">=", "6" ] } ] } ] @@ -420,7 +420,7 @@ { "math": [ "u_spell_level('vita_stop_infection')", ">=", "12" ] }, { "or": [ - { "math": [ "u_spell_level('vita_pain_split')", ">=", "8" ] }, + { "math": [ "u_spell_level('vita_concentrated_healing')", ">=", "8" ] }, { "math": [ "u_spell_level('vita_cure_disease')", ">=", "12" ] } ] } @@ -469,7 +469,7 @@ }, { "or": [ - { "math": [ "u_spell_level('vita_pain_split')", ">=", "10" ] }, + { "math": [ "u_spell_level('vita_concentrated_healing')", ">=", "10" ] }, { "math": [ "u_spell_level('vita_remove_poison')", ">=", "7" ] }, { "math": [ "u_spell_level('vita_blood_purge')", ">=", "5" ] } ] diff --git a/data/mods/MindOverMatter/powers/vitakinesis_eoc.json b/data/mods/MindOverMatter/powers/vitakinesis_eoc.json index 864016ba04934..1c2c347100463 100644 --- a/data/mods/MindOverMatter/powers/vitakinesis_eoc.json +++ b/data/mods/MindOverMatter/powers/vitakinesis_eoc.json @@ -1035,7 +1035,6 @@ { "math": [ "u_hp('arm_r')", "=", "max( u_hp('arm_r'), 5)" ] }, { "math": [ "u_hp('leg_l')", "=", "max( u_hp('leg_l'), 5)" ] }, { "math": [ "u_hp('leg_r')", "=", "max( u_hp('leg_r'), 5)" ] }, - { "u_cast_spell": { "id": "vita_pain_split", "hit_self": true } }, { "math": [ "u_vitamin('redcells')", "=", "0" ] }, { "math": [ "u_vitamin('bad_food')", "=", "0" ] }, { "math": [ "u_vitamin('blood')", "=", "0" ] }, diff --git a/data/mods/MindOverMatter/recipes/research.json b/data/mods/MindOverMatter/recipes/research.json index 0fd38d063d3bd..feb136a7e9b0d 100644 --- a/data/mods/MindOverMatter/recipes/research.json +++ b/data/mods/MindOverMatter/recipes/research.json @@ -142,7 +142,7 @@ "and": [ { "roll_contested": { "math": [ "u_skill('metaphysics')" ] }, "difficulty": 11 }, { "roll_contested": { "math": [ "u_skill('chemistry')" ] }, "difficulty": 8 }, - { "math": [ "u_spell_level('vita_pain_split')", ">=", "8" ] }, + { "math": [ "u_spell_level('vita_concentrated_healing')", ">=", "8" ] }, { "math": [ "u_spell_level('vita_stop_infection')", ">=", "6" ] }, { "math": [ "u_spell_level('vita_healing_trance')", ">=", "2" ] } ]